ここは今からストレージです。

Ceph Pool の利用可能容量の計算法

f:id:ututaq:20200630133258p:plain

こんにちは、うつぼです。
今日は小ネタで Ceph の capacity usage について説明します。

Ceph はどれくらいの容量が使えるのか分かりづらいことで定評があります。
いや分かることは分かるんですが、「なんでそーなるの?」と欽ちゃんライクになる人もいるでしょう。今日はそこを紐解いていきましょう。

ceph df を見ていく

ceph df の出力

まず、Ceph の Pool の capacity usage は、ceph df コマンドで見ることができます。
0.5 TiB (512 GiB) の osd を1つだけ持つシンプルな 3 node の Ceph クラスターを用意します。直後に、

  • 3x replicated pool
  • 2x replicated pool
  • 2+1 erasure coded pool

の3つの Pool を作り、ceph df を実行してみます。

sh-4.4# ceph df   
RAW STORAGE:
    CLASS     SIZE        AVAIL       USED       RAW USED     %RAW USED 
    ssd       1.5 TiB     1.5 TiB     47 MiB      3.0 GiB          0.20 
    TOTAL     1.5 TiB     1.5 TiB     47 MiB      3.0 GiB          0.20 
 
POOLS:
    POOL           ID     STORED      OBJECTS     USED        %USED     MAX AVAIL 
    pool_3rep       1         0 B           0         0 B         0       433 GiB 
    pool_2rep       2         0 B           0         0 B         0       650 GiB 
    pool_2+1ec      3         0 B           0         0 B         0       867 GiB 

これはまだクライアントから全然使われてない状態です。

上の RAW STORAGE には全ての osd を合算した usage が書かれます。ここはここでまあいいとして、問題は下の POOLS です。

妙に少ない MAX AVAIL と full ratio

右端の MAX AVAIL が Pool ごとに違います。名前からしても、冗長度が違う Pool ごとに値が違うところからしても、Pool に保存できる最大のデータ容量のようですね。でも、ちょっと少ないですよね。
1 node あたり 512 GiB あるのだから、例えば 3x replicated pool の場合、仮に何やかんや無条件に内部処理で引かれる分 (個人的にこれを税金と呼んでいる) があるとしても、433 GiB は少なすぎる。

なぜこんなに少ないのか?どういう計算をしているのか?

これは、osd に設定されている full ratio が主な原因です。

sh-4.4# ceph osd dump | grep ^full_ratio
full_ratio 0.85

full ratio は、『osd の使用可能容量の何%まで使ったら osd は容量フルとして write できないようにする』というパラメータです。
つまり osd の容量に full ratio をかけた分が、Ceph で使える容量ということですね。

デフォルトは 0.95 なんですが、この環境では上の通り 0.85 でした。これを頭に入れて 3x replicated pool で計算をしてみると、

512 GiB x 0.85 = 435.2 GiB

大分近い数値になりました。

Pool の MAX AVAIL を計算する式

正確な計算式は、次のようになります。

 pool.MAX\ AVAIL = \\ \\ \ \ \ \ \{osd.AVAIL - ( osd.SIZE \times ( 1 - full\ ratio )\ )\ \} \times num\ of\ osd \div pool.size

osd.AVAIL は、その時点の osd の空き容量 であり、osd.SIZE は元々の osd の容量です。(ややこしい)
これらは ceph osd df で確認できます。

sh-4.4# ceph osd df
ID CLASS WEIGHT  REWEIGHT SIZE    RAW USE DATA   OMAP META  AVAIL   %USE VAR  PGS STATUS
 0   ssd 0.49899  1.00000 511 GiB 1.0 GiB 19 MiB  0 B 1 GiB 510 GiB 0.20 1.00 147     up
 1   ssd 0.49899  1.00000 511 GiB 1.0 GiB 19 MiB  0 B 1 GiB 510 GiB 0.20 1.00 146     up
 2   ssd 0.49899  1.00000 511 GiB 1.0 GiB 19 MiB  0 B 1 GiB 510 GiB 0.20 1.00 147     up
                    TOTAL 1.5 TiB 3.1 GiB 56 MiB  0 B 3 GiB 1.5 TiB 0.20

どの osdosd.AVAIL = 510 GiB、osd.SIZE = 511 GiB であることが分かります。これらと num of osd(osdの数) = 3 とpool.size=3(3x replicated pool) を式に代入すると、

{ 510 - ( 511 x ( 1 - 0.85 ) ) } x 3 / 3 = 433.35

となって MAX AVAIL が出てきます。
2x replicated pool では pool.size=2 として、2+1 ec pool では pool.size を (2+1)/2 とすることで、同様に計算できます。

  • 2x replicated pool --> pool.size = 2 : { 510 - ( 511 x ( 1 - 0.85 ) ) } x 3 / 2 = 650.025
  • 2+1 ec pool --> pool.size = (2+1)/2 : { 510 - ( 511 x ( 1 - 0.85 ) ) } x 3 / { (2+1) / 2 } = 866.7

osd の AVAIL がバラバラな場合

クラスター作成直後だとデータが入っていないので osd の AVAIL は同じでした。しかしデータが入ってくると osd の AVAIL はバラバラになります。Ceph は精密に全ての osd を均等に利用することはないからです。

先程のクラスターにデータを入れ始めて、途中で osd を 6つに増やしてまた入れた結果が次の例です。

sh-4.4# ceph df
RAW STORAGE:
    CLASS     SIZE        AVAIL       USED        RAW USED     %RAW USED 
    ssd       3.0 TiB     2.3 TiB     658 GiB      664 GiB         21.65 
    TOTAL     3.0 TiB     2.3 TiB     658 GiB      664 GiB         21.65 
 
POOLS:
    POOL           ID     STORED      OBJECTS     USED        %USED     MAX AVAIL 
    pool_3rep       1     112 GiB      28.23k     337 GiB     18.76       487 GiB 
    pool_2rep       2     113 GiB      26.95k     227 GiB     13.45       730 GiB 
    pool_2+1ec      3      62 GiB      15.49k      93 GiB      6.01       973 GiB 
sh-4.4#
sh-4.4# ceph osd df
ID CLASS WEIGHT  REWEIGHT SIZE    RAW USE DATA    OMAP    META     AVAIL   %USE  VAR  PGS STATUS 
 0   ssd 0.49899  1.00000 511 GiB 191 GiB 190 GiB  36 KiB 1024 MiB 320 GiB 37.31 1.72 110     up 
 3   ssd 0.49899  1.00000 511 GiB  43 GiB  42 GiB     0 B    1 GiB 468 GiB  8.33 0.38  70     up 
 1   ssd 0.49899  1.00000 511 GiB 184 GiB 183 GiB  35 KiB 1024 MiB 327 GiB 35.96 1.66 112     up 
 4   ssd 0.49899  1.00000 511 GiB  15 GiB  14 GiB     0 B    1 GiB 496 GiB  3.00 0.14  64     up 
 2   ssd 0.49899  1.00000 511 GiB 186 GiB 185 GiB  36 KiB 1024 MiB 325 GiB 36.39 1.68 101     up 
 5   ssd 0.49899  1.00000 511 GiB  45 GiB  44 GiB     0 B    1 GiB 466 GiB  8.89 0.41  79     up 
                    TOTAL 3.0 TiB 664 GiB 658 GiB 108 KiB  6.0 GiB 2.3 TiB 21.65                 
MIN/MAX VAR: 0.14/1.72  STDDEV: 15.03

osd の AVAIL がばらついています。この場合でも Pool の MAX AVAIL は表示されているのですが、これの場合はどう計算するのでしょうか。

正解は、『一番少ない osd.AVAIL を数値を先の計算式に入れて計算する』です。

上の 6 つの osd の内、最も osd.AVAIL が少ないのは、osd.0 の 320 GiB です。これと osd.SIZE = 511 と num of osd=6 を計算式に入れると、

  • 3x replicated pool: { 320 - ( 511 x ( 1 - 0.85 ) ) } x 6 / 3 = 486.7
  • 2x replicated pool: { 320 - ( 511 x ( 1 - 0.85 ) ) } x 6 / 2 = 730.05
  • 2+1 ec pool : { 320 - ( 511 x ( 1 - 0.85 ) ) } x 6 / { (2+1) / 2 } = 973.4

となり、MAX AVAIL と同じことが分かります。

改めて全ての osd.AVAIL の中で最小の値を採用することを反映した計算式と、この様子を図で表したものを載せます。

 pool.MAX\ AVAIL = \\ \\ \ \ \ \ \{\ min(osd.AVAIL) - ( osd.SIZE \times ( 1 - full\ ratio )\ )\ \} \times num\ of\ osd \div pool.size
f:id:ututaq:20200630225712p:plain
Ceph Pool の MAX AVAIL

まとめ

Ceph Pool の capacity usage について説明しました。
Ceph の設計をする時には、full ratio を加味して容量を見積もる必要があることは盲点になりやすいので、注意しましょう。full ratio line の上にある屋根裏部屋は (デフォルトで) 5% ですが、12 TB の玉を使えば 600GB ですから、なかなかバカになりません。
また MAX AVAIL の計算方法も紹介しましたが、はっきり言ってこれが分からないことで運用上すごく困ることにはあんまりならないと思います。あくまで小ネタです。

Pool で利用できる領域が減ってくると、そのうち osd nearfull の WARNING が出てきます。もうすぐ full になるから対処してねというやつです。nearful ratio はデフォルトで 0.85 です。
nearfull が来たらすぐに osd を追加しましょう。それが本道です。とは言え、どうしても新しい玉が来るまで持ちこたえられないという時の緊急対処として、full ratio を引き上げるとか、(pg のばらつきが大きくないと効果ゼロだが) osd を reweight して rebalance してみるとかして、既存 osd の AVAIL を押し広げて多少持ちこたえる小技があります。

とまあ最後まで小ネタでした。今日はここまで。