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.8k
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.4k
しきい値監視からの卒業! Prometheus による機械学習を用いた異常検知アラートの実装
takutakahashi
0
1.8k
15年以上動くECシステムをクラウドネイティブにするためにやっていること
takutakahashi
1
1.9k
カラーミーショップの 可用性向上のための インフラ刷新
takutakahashi
1
420
ペパボが求める「守って攻める」インフラとは?
takutakahashi
4
620
Site Reliability を向上するためにやったことすべて
takutakahashi
11
2.1k
Deep-dive KubeVirt
takutakahashi
2
1.7k
Other Decks in Programming
See All in Programming
『ドメイン駆動設計をはじめよう』のモデリングアプローチ
masuda220
PRO
8
540
Micro Frontends Unmasked Opportunities, Challenges, Alternatives
manfredsteyer
PRO
0
110
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
Jakarta EE meets AI
ivargrimstad
0
240
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
RubyLSPのマルチバイト文字対応
notfounds
0
120
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
3
700
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
940
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
120
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
340
.NET のための通信フレームワーク MagicOnion 入門 / Introduction to MagicOnion
mayuki
1
1.8k
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
88
5.7k
Automating Front-end Workflow
addyosmani
1366
200k
A Philosophy of Restraint
colly
203
16k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
The Invisible Side of Design
smashingmag
298
50k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Why Our Code Smells
bkeepers
PRO
334
57k
Art, The Web, and Tiny UX
lynnandtonic
297
20k
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 はいいぞ