Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rook/Ceph on ZFS
Search
Takuya TAKAHASHI
October 02, 2020
Programming
1
2k
Rook/Ceph on ZFS
Japan Rook Meetup #4 でお話した内容です。
Takuya TAKAHASHI
October 02, 2020
Tweet
Share
More Decks by Takuya TAKAHASHI
See All by Takuya TAKAHASHI
顧客の画像データをテラバイト単位で配信する 画像サーバを WebP にした際に起こった課題と その対応策 ~継続的な取り組みを添えて~
takutakahashi
4
1.7k
実例から学ぶ Kubernetes Custom Controller の状態管理
takutakahashi
0
1.8k
しきい値監視からの卒業! Prometheus による機械学習を用いた異常検知アラートの実装
takutakahashi
0
2.4k
15年以上動くECシステムをクラウドネイティブにするためにやっていること
takutakahashi
1
2.2k
カラーミーショップの 可用性向上のための インフラ刷新
takutakahashi
1
500
ペパボが求める「守って攻める」インフラとは?
takutakahashi
4
700
Site Reliability を向上するためにやったことすべて
takutakahashi
11
2.2k
Deep-dive KubeVirt
takutakahashi
2
1.9k
Other Decks in Programming
See All in Programming
知られているようで知られていない JavaScriptの仕様 4選
syumai
0
640
Level up your Gemini CLI - D&D Style!
palladius
1
130
モダンJSフレームワークのビルドプロセス 〜なぜReactは503行、Svelteは12行なのか〜
fuuki12
0
130
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
1
130
Building AI with AI
inesmontani
PRO
1
360
なぜ強調表示できず ** が表示されるのか — Perlで始まったMarkdownの歴史と日本語文書における課題
kwahiro
12
7.4k
All(?) About Point Sets
hole
0
230
AIの弱点、やっぱりプログラミングは人間が(も)勉強しよう / YAPC AI and Programming
kishida
13
5.5k
Evolving NEWT’s TypeScript Backend for the AI-Driven Era
xpromx
0
210
AWS CDKの推しポイントN選
akihisaikeda
1
210
20251127_ぼっちのための懇親会対策会議
kokamoto01_metaps
2
130
競馬で学ぶ機械学習の基本と実践 / Machine Learning with Horse Racing
shoheimitani
14
14k
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
Scaling GitHub
holman
464
140k
Building Applications with DynamoDB
mza
96
6.8k
KATA
mclloyd
PRO
32
15k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
For a Future-Friendly Web
brad_frost
180
10k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Become a Pro
speakerdeck
PRO
30
5.6k
Building Adaptive Systems
keathley
44
2.8k
It's Worth the Effort
3n
187
29k
Transcript
Rook/Ceph on ZFS Japan Rook Meetup #4 @takutaka1220 Takuya Takahashi
アジェンダ - 自己紹介 - 環境構築 - 計測 - 考察
自己紹介します
自己紹介 - 高橋 拓也 - GMO ペパボという会社でインフラエンジニアをしています - ストレージは趣味です -
https://github.com/takutakahashi - https://twitter.com/takutaka1220 - https://www.takutakahashi.dev
突然ですが
ZFS はいいぞ
ZFS (Zettabyte File System) とは? - CoW な多機能ファイルシステム - Block
Device をまとめて Storage Pool を構成 - RAID (シングルパリティの RAIDZ, ダブルパリティの RAIDZ2 など) - SnapShot, Clone - Export - 圧縮 - 重複排除 - Storage Pool から filesystem や Block Device (zvol) の切り出しができる - Solaris が源流、FreeBSD が主流、Linux にもあり (ZFS on Linux) - 最近 Ubuntu でデフォルトで利用できるようになった - macOS や Windows でも使えるらしい (OpenZFS)
とある自鯖ユーザーの悩み
おうち k8s を作ったぞ! Master * 3 + Node * 3
で冗長構成だ!
Node をまたがった Persistent Volume が欲しいぞ
Rook/Cephというものがあるらしい
たくさんの Block Device を ひとつにまとめるらしいぞ
ZFS なら 無限に Block Device を生やせるぞ
ZFS に乗せてみよう!
検証環境スペック - Node 1 - Intel(R) Core(TM) i5-10210U CPU @
1.60GHz - 32GB Memory (single channel) - SanDisk SSD Ultra 3D 1TB * 2 - Node 2 - Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz - 16GB Memory - SanDisk SSD Ultra 3D 1TB * 2 - Node 3 - 今回は使わない
検証環境スペック - Cluster - k3s Master * 3 (rpi) +
Node * 3 - version: v1.18.6+k3s1 - Rook - version: v1.3.7 - Ceph - version: v15.2.4
環境構築
SSD1 zvol ZFS でできたなにか OSD OSD OSD Ceph Cluster /dev/rbd0
環境構築 - OSD のストレージプロビジョニング - Block Device? Directory? - Block
Device を割り当てる方式が推奨らしい - zvol を使おう!
SSD1 zvol OSD zvol OSD zvol OSD Ceph Cluster /dev/rbd0
zfs pool
環境構築 - Block Storage を利用する - zvol をどうやってプロビジョニングする? - →
pvc による dynamic provisioning を設定する - local provisioning してくれる provisioner が必要 - openebs/zfs-localpv が便利
環境構築 - openebs/zfs-localpv が便利 - https://github.com/openebs/zfs-localpv - zfs pool から
fs, zvol を dynamic provisioning してくれるやつ - local provision なので、ノードを跨いでマウントできる pvc は作成できない - openEBS - https://openebs.io/ - rook 競合な Cloud Native SDS
環境構築 zfs-localpv のデプロイは一発 kubectl apply -f https://raw.githubusercontent.com/openebs/zfs-localpv/master/deploy/zfs-operator.yaml
SSD1 zvol pvc OSD zvol pvc OSD zvol pvc OSD
Ceph Cluster /dev/rbd0 zfs pool これを目指す
SSD1 zfs pool 今はまだ、これ
localpv StorageClass をつくる
StorageClass
‘zfs’ だと filesystem ‘ext(2-4)|xfs|btrfs’ だと block device(zvol) になる block device
でしか OSD on pvc は動作しない allowedTopologies を指定して pool のない node に スケジュールされないようにする
環境構築 - Pool の空き容量は考慮してくれない - とにかく zvol 作りに行くし、作れなかったとしても zvol が作れたと嘘を付く
- ハマった - デフォルトでは snapshot を持つ vol は削除できない - snapshot を自動生成するようにしていたら削除できずに容量使い果たした
SSD1 zvol pvc zvol pvc zvol pvc zfs pool pvc
ができた
環境構築 - cephcluster.yaml を書く - node が少ないので、以下の設定が必要となる - mon が同一ノードに起動することを許可する
- osd を同一ノードに建てるために topologySpreadConstraints.maxSkew を増やす
node が足りないので 複数 node に立つことを 許可する
maxSkew: いくつまで 障害ドメインの差を許容するか 1node なのでたくさん設定する OSD を pvc に載せる設定
SSD1 zvol pvc OSD zvol pvc OSD zvol pvc OSD
Ceph Cluster zfs pool クラスタができた
クラスタができた
計測だ!
計測方法 • 以下の条件で fio を 10回測定し、中央値を計測 ◦ rw=read/write ◦ size=1g
◦ numjobs=1 • bandwidth, iops を抽出し記録 • pool の replicated size は 2とする
計測方法 • 以下の条件で fio を 10回測定し、中央値を計測 ◦ rw=read/write ◦ size=1g
◦ numjobs=1 • bandwidth, iops を抽出し記録 • pool の replicated size は 2とする 「妥当な計測」がなんなのか手探りで計測したので これは違うぞ!という内容があったら twitter でメンションください
まずは raw device と ZFS の実力
まずは raw device と ZFS の実力 1. raw device を
ext4 でフォーマットした vol 2. zfs プールから切り出した zvol a. single device b. 2 devices (striped)
basic benchmark read (bw) read (iops) write (bw) write (iops)
raw device 415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k
basic benchmark read (bw) read (iops) write (bw) write (iops)
raw device 415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k zfs にするだけで性能アップ
ZFS はキャッシュが命 • ARC というインメモリキャッシュを持つ • ARC のキャッシュヒット率が高くなると速い • ZFS
に載せるだけで速くなったのはそのため • fio の read benchmark はめちゃめちゃキャッシュに乗る...
ベンチ中の iostat の様子を 見てみる
1 device read iostat の結果
zd0 … zvol raw … raw device (sda とか)
x軸は時系列
raw は zd0 より書き込み開始が遅い (fio は tmpfile を書いてから計測する )
zd0 で read が走るが、 raw は IO が発生しない (すべてキャッシュから読んでいる )
キャッシュヒット率を見たい?
arcstat - ZFS のキャッシュの状況を確認できるスゴイヤツ - キャッシュミスの割合や、キャッシュサイズなどを確認できる - zfsonlinux に同梱されている -
https://packages.ubuntu.com/ja/xenial-updates/amd64/zfsutils-linux/filelist
1 device read arcstat の結果
秒間 arc アクセス
read のうち ミスしたアクセス
キャッシュミス率
arc の容量
arc target size キャッシュに 載せようとしているサイズ
None
read IO が発生したのはここ
キャッシュミスした アクセスはない
striped pool の read iostat
zvol, raw に書いて キャッシュから読む 挙動は同じ
raw1, 2 の IO は 全く同じ量出ている (グラフが重なっている )
シングルノード性能 いよいよ Ceph
シングルノード性能 - OSD を全て node 1 に寄せて計測 - 1 device
pool, 2 devices pool でそれぞれ計測 - 3台の OSD を起動させた
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk 1504MiB/s 385k 2221MiB/s 569k 1node-2disk 1517MiB/s 388k 2265MiB/s 580k シングルノード性能
read の iostat (1 device)
zvol に直接書くより 書き込みが遅い (約半分)
1 device read iostat の結果
osd へのアクセスは ひとつだけ少ない
キャッシュの状態を arcstat で見る
ここが read のスパイク
全てキャッシュから読んでいる (miss がゼロ)
write の iostat (1 device)
rbd0 よりも raw device のほうが 転送量が多い
zvol へのアクセスは ひとつだけ突出している read とは逆
シングルノード性能 - OSD を3 → 6 に増やすとどうなる?
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k シングルノード性能
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k シングルノード性能 1disk, 2disk どちらにおいても若干の性能劣化が見られる
read の iostat (1 device)
osd の分散が大きくなった
write にコブができている IO 待ちしている?
マルチノード性能
マルチノード性能 - 2disk striped なノードを2つ利用して計測 - ノード間は 1GbE で接続
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k 2node-2disk (3osd) 計測ノードに 1osd 180MiB/s 46.1k 2188MiB/s 560k 2node-2disk (5osd) 計測ノードに 2osd 155MiB/s 39.6k 2231MiB/s 571k マルチノード性能
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k 2node-2disk (3osd) 計測ノードに 2osd 180MiB/s 46.1k 2188MiB/s 560k 2node-2disk (5osd) 計測ノードに 2osd 155MiB/s 39.6k 2231MiB/s 571k マルチノード性能 OSD が増えると 性能が劣化する
read の iostat (1 device)
rbd0 よりも zd0, zd1 のほうが IO が出ている
zd0 + zd1 < rbd0 なので キャッシュはある程度 効いている
1node の read と スケールを合わせてみた
write は誤差の範囲
read は倍くらい違う
OSD が増えると 性能が劣化している
OSD を極端に増やしてみる
OSD を極端に増やしてみる - 1node 2disk な cluster に大量の OSD を設置する
- なるべく object が乗る osd が分散するように tmpfile のサイズを 10g にした - 30, 50 osd で計測
None
一部の OSD が CrashLoopBackOff
None
None
とりあえず増やしたら動いた
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k 1node-2disk (30osd) 181MiB/s 46.4k 207MiB/s 52.9k 1node-2disk (50osd) 158MiB/s 40.4k 144MiB/s 36.9k OSD を極端に増やしてみる
osd 30 read の iostat osd を抜粋しました
書き込みと IO 待ちを 繰り返している
OSD ごとの性能差が 大きくなった
rbd0 に常に write io が 発生している
トップラインが伸びた
arcstat の結果
read io はこのへん ひとけた増えている
ほぼキャッシュヒット (miss がほぼない)
read (bw) read (iops) write (bw) write (iops) raw device
415MiB/s 106k 2498MiB/s 639k zfs (single device) 1058MiB/s 271k 2498MiB/s 639k zfs (2 devices) 1100MiB/s 282k 2485MiB/s 636k 1node-1disk (3osd) 1504MiB/s 385k 2221MiB/s 569k 1node-1disk (6osd) 1333MiB/s 341k 2124MiB/s 544k 1node-2disk (3osd) 1517MiB/s 388k 2265MiB/s 580k 1node-2disk (6osd) 1499MiB/s 384k 2111MiB/s 541k 1node-2disk (30osd) 181MiB/s 46.4k 207MiB/s 52.9k 1node-2disk (50osd) 158MiB/s 40.4k 144MiB/s 36.9k ベンチマークの結果は悪い...
このトップラインは すべてキャッシュ 30 OSD と 50 OSD の read グラフを
重ねてみる
このトップラインは すべてキャッシュ write io の 帯域はだいたい同じ
このトップラインは すべてキャッシュ IO 待ちが 長くなっている
このトップラインは すべてキャッシュ トップラインが 非常に低速
50 OSD の arcstat
書き込み時は arc に乗っている
read 開始前に キャッシュが 破棄されている
キャッシュミス率が 40% を超えている
なぜ?
考察
考察 • Read IO は伸びる ◦ 特にキャッシュを効かせると非常に伸びる ◦ zfs の特性を
Rook/Ceph でも活かすことができる ▪ 一度ファイルを置いたら read しかしないワークロード ▪ メモリが余っていればだけど ... • Write IO は変化なし ◦ オーバーヘッド分少なくなる ◦ 1 Pool あたりの OSD の数が増えるとオーバーヘッドが大きくなる
考察 • Rook/Ceph on ZFS 構築の難易度 ◦ めちゃめちゃ簡単 ◦ Multiple
Devices 界で一番簡単なのでは? ◦ ご家庭に余った k8s クラスタとディスクがあればぜひお試しを
考察 • 障害ドメイン ◦ Storage Pool が障害ドメイン ▪ OSD 分割しても
Pool が死んだら全て死ぬ ▪ ceph on zfs による障害リスクの上昇はない • (うまく OSD 分散できれば) • Pool の件があるからドメイン分割には少し気を使う必要がある
考察 - zfs はいいぞ ◦ ド安定 ◦ わかりやすい CLI ◦
機能が豊富 ▪ ストレージプールの大きさを動的に増やしたり ▪ ライトホール問題のない RAID 組めたり ▪ pool ごとバックアップ取ったり • (OSD のバックアップいるか? )
ZFS はいいぞ