Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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
1.6k
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
実例から学ぶ Kubernetes Custom Controller の状態管理
takutakahashi
0
1.2k
しきい値監視からの卒業! Prometheus による機械学習を用いた異常検知アラートの実装
takutakahashi
0
1.5k
15年以上動くECシステムをクラウドネイティブにするためにやっていること
takutakahashi
1
1.7k
カラーミーショップの 可用性向上のための インフラ刷新
takutakahashi
1
400
ペパボが求める「守って攻める」インフラとは?
takutakahashi
4
600
Site Reliability を向上するためにやったことすべて
takutakahashi
11
2k
Deep-dive KubeVirt
takutakahashi
2
1.5k
Other Decks in Programming
See All in Programming
Compose-View Interop in Practice (mDevCamp 2024)
stewemetal
0
130
検証も兼ねて個人開発でHonoとかと向き合った話
hanetsuki
1
900
GitHub Copilotのススメ
marcy731
1
200
StoreKit2によるiOSのアプリ内課金のリニューアル
kangnux
0
110
SIMD Parallel Programming with the Vector API
josepaumard
0
170
TYPO3 v13 – The road to LTS: What's new and new APIs
luisasofie_xoxo
0
200
MetricKitで予期せぬ終了を検知する話 / Detect unexpected termination with MetricKit
nekowen
1
180
ADRを一年運用してみた/adr_after_a_year
hanhan1978
7
2.4k
Build Apps for iOS, Android & Desktop in 100% Kotlin With Compose Multiplatform (mDevCamp 2024)
zsmb
0
330
AWS Application Composerで始める、 サーバーレスなデータ基盤構築 / 20240406-jawsug-hokuriku-shinkansen
kasacchiful
1
260
Node.js v22 で変わること
yosuke_furukawa
PRO
9
3.3k
スキーマ駆動開発による品質とスピードの両立 - 私達は何故、スキーマを書くのか
kentaroutakeda
0
170
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
782
250k
The Brand Is Dead. Long Live the Brand.
mthomps
49
28k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
221
21k
How GitHub Uses GitHub to Build GitHub
holman
468
290k
Side Projects
sachag
451
41k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
244
20k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
30
6k
The Pragmatic Product Professional
lauravandoore
25
5.8k
Fireside Chat
paigeccino
21
2.6k
No one is an island. Learnings from fostering a developers community.
thoeni
16
2.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
355
18k
Being A Developer After 40
akosma
57
580k
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 はいいぞ