`rados bench` で Rook/Ceph クラスタのベンチマーキングを行う

Rook/Ceph クラスタの導入検討に際し、ベンチマークは必ず求められるものと思います。

ストレージやファイルシステムのベンチマーク用ツールとして、 fio や bonnie++ など有名なオープンソースソフトウェアが存在します。Rook/Ceph でも、これらの使用を検討される方が多いのではないでしょうか。

それらのソフトウェアでの計測も無駄ではありません。しかし Rook/Ceph の場合は、それらのツールを用いる前に `rados bench` での計測をお勧めします。

Ceph は RADOS という KVS を基盤とし、RBD、CephFS、NFS 等々のストレージインタフェースを提供しています。
つまり、基盤である RADOS 層での性能が出せていないと、上層の性能も出ません。

Ceph には RADOS を直接操作する `rados` という CLI が用意されています。そのサブコマンド `bench` は、読み書きのベンチマークを取得し、判りやすい形式で指標を出力します。

本稿では、実況チュートリアル形式で、使い方を概説します。

# 前提

Rook/Ceph では、CLI 操作のための `rook-ceph-tools` という deployment が提供されています。
本稿では既に rook-ceph-tools が、名前空間 `rook-ceph` にデプロイされているものとして話を進めます。

# 初めての `rados bench`

まずは深く考えず、実行してみましょう。

はじめに、ベンチマーク対象となる pool を探します。

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- ceph osd pool ls
```

下記のような一覧が得られます。内容は、お使いの環境により異なるはずです。

```
.mgr
replicapool
testfs-metadata
testfs-data0
```

本稿では `testfs-data0` を、ベンチマーク対象とします。

# 書き込みベンチマーク

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- rados bench -p testfs-data0 10 write
```

`10` は、計測を行う秒数です。`write` は、書き込み性能の計測を指示しています。

10 秒間、途中経過が表示されたあと…

```
hints = 1
Maintaining 16 concurrent writes of 4194304 bytes to objects of size 4194304 for up to 10 seconds or 0 objects
Object prefix: benchmark_data_rook-ceph-tools-555c879675-qv_257860
  sec Cur ops   started  finished  avg MB/s  cur MB/s last lat(s)  avg lat(s)
    0       0         0         0         0         0           -           0
    1      16        48        32   127.994       128    0.165356    0.349761
    2      16        88        72   143.987       160    0.530343    0.407533
    3      16       127       111   147.985       156    0.175736    0.395974
    4      16       164       148   147.928       148    0.218061    0.391926
    5      16       198       182   145.537       136    0.413798    0.418438
    6      16       238       222   147.814       160    0.445741    0.412941
    7      16       270       254   144.983       128      0.6776    0.415378
    8      16       311       295   147.355       164    0.142006    0.422009
    9      16       350       334   148.313       156    0.619627    0.420417
   10      16       383       367   146.681       132    0.286598    0.421052
```

…結果が表示されます。

```
Total time run:         10.4443
Total writes made:      383
Write size:             4194304
Object size:            4194304
Bandwidth (MB/sec):     146.682
Stddev Bandwidth:       14.3666
Max bandwidth (MB/sec): 164
Min bandwidth (MB/sec): 128
Average IOPS:           36
Stddev IOPS:            3.59166
Max IOPS:               41
Min IOPS:               32
Average Latency(s):     0.428837
Stddev Latency(s):      0.274607
Max latency(s):         1.79436
Min latency(s):         0.0270248
Cleaning up (deleting benchmark objects)
Removed 383 objects
Clean up completed and total clean up time :0.178074
```

> ちょっと待って! 私の IOPS…遅すぎ? (Average IOPS: 36)

と思われるかもしれません。これには理由があります。

多くのストレージソリューションで、公表最大性能は、小さなサイズで達成されます。典型的には 4KB や 16KB です。
一方、`rados bench` のデフォルトの書き込みサイズは 4MB です。
一般に、書き込みサイズが大きくなると IOPS は低下します。

名誉回復のため、書き込みサイズを指定して再計測してみます。

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- rados bench -p testfs-data0 10 write -b 4096 --no-cleanup
```

`-b 4096` によって、書き込みサイズを 4096 バイト(4KiB) と指定しています。

再計測とは直接関係ないのですが、`--no-cleanup` を追加しています。これにより、ベンチマークの後片付けが行われなくなります。次に行う読み込みベンチマークのために必要です。

下記、実行結果です。

```
Total time run:         10.02
Total writes made:      9172
Write size:             4096
Object size:            4096
Bandwidth (MB/sec):     3.57567
Stddev Bandwidth:       0.446151
Max bandwidth (MB/sec): 4.13672
Min bandwidth (MB/sec): 2.95703
Average IOPS:           915
Stddev IOPS:            114.215
Max IOPS:               1059
Min IOPS:               757
Average Latency(s):     0.0174597
Stddev Latency(s):      0.0431238
Max latency(s):         0.582154
Min latency(s):         0.00281438
```

4MB 時と比較すると、bandwidth は下がります。IOPS とトレードオフの関係なので、やむを得ません。
IOPS は平均で 915 と出ました。この環境では、下記理由により、この程度の IOPS に留まるのは想定の範囲です。

* この環境での OSD では、比較的低速 (500 IOPS) なストレージを使っています。
* Ceph は書き込み時に、 3 つの OSD へ順に書き込みます。

# 読み込みベンチマーク

つづいて読み込み性能を測ります。読み込み方法はシーケンシャルとランダムを選べます。

## シーケンシャル読み込み

測ってみましょう。

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- rados bench -p testfs-data0 10 seq --no-cleanup
```

```
Total time run:       0.798155
Total reads made:     9172
Read size:            4096
Object size:          4096
Bandwidth (MB/sec):   44.8887
Average IOPS:         11491
Stddev IOPS:          0
Max IOPS:             9169
Min IOPS:             9169
Average Latency(s):   0.00138091
Max latency(s):       0.188503
Min latency(s):       0.000181109
```

シーケンシャル読み込みの IOPS は、書き込み比 10 倍以上の値となりました。bandwidth も書き込みよりよい数値となっています。
latency も書き込みよりよい値なのですが、読み書きいずれも最大最小の差が大きいのが気になるところです。

## ランダム読み込み

 `seq` を `rand` に変更する他は、シーケンシャル読み込みと同じです。

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- rados bench -p testfs-data0 10 rand --no-cleanup
```

```
Total time run:       10.0007
Total reads made:     144762
Read size:            4096
Object size:          4096
Bandwidth (MB/sec):   56.544
Average IOPS:         14475
Stddev IOPS:          3794
Max IOPS:             17507
Min IOPS:             5522
Average Latency(s):   0.00109415
Max latency(s):       0.555312
Min latency(s):       0.000152902
```

Ceph はシーケンシャルよりもランダムのほうが性能が出る傾向があり、それを裏付ける結果が出ました。

# cleanup

上記のようなベンチマークは、計測ごとに値が変動します。継続時間を長く取るか、何回か計測してメタ解析を行うと、より信頼性のある値が得られます。

十分に計測が行えたら、計測で使ったオブジェクトを削除します。

```
kubectl exec -it -n rook-ceph deploy/rook-ceph-tools -- rados cleanup -p testfs-data0
```

クリーンアップには時間がかかる場合があります。しばらく待つと、下記のように削除されたオブジェクトの数が表示され終了します。

```
Removed 9172 objects
```

# どう改善に結びつける?

> 数値は採れました。次はどうしましょう?

いくつか案はあります。

* ストレージの種類を変えて比べてみる。
* ノードの種類やサイズを変えてみる。
* ネットワーク構成を変えてみる。
* Linux のカーネルパラメータについて検討する。

お手元の環境がオンプレかクラウドか、クラウドにしても K8s がマネージドかセルフホストかで、変更の容易性は変わると思いますが、何らか改善の方法はあるかと思います。

一方、お勧めしないのは「rados や ceph の CLI でチューニングを試みる」です。

最近のバージョンの ceph では、自己最適化能力が備わっています。
また、Rook は、得られた custom resource の値をもとにして、(主にメモリ関連の)パラメータを最適化します。
人手を入れてしまうと、却って調子を崩しがちです。

# サポート承ります

合同会社もなみ屋では、[FLOSS プロフェッショナルサポート](https://www.monami-ya.jp/pages/floss-pro-support/)の一環で Rook に関する技術支援を行っています。またオプションで Ceph に関する技術支援も承ります。ご興味のある方は是非お問い合わせください。

(当記事は[合同会社もなみ屋の技術ブログ](https://www.monami-ya.jp/posts/2023/06/11/using-rados-benchmark/)からの転載です。)