Cephの紹介
この記事はRookだらけの Advent Calendar 2019 2日目の記事です。
Rookとは少し離れますが、Cephの説明をしたいと思います。
Ceph
Cephの特徴はググればたくさん出てくるので、詳しく知りたい人はググって下さい。ざっくり簡単に書きます。
- オープンソースのSoftware-Defined Storage
- Object, Block, Fileのユースケースに対応するUnified Storage
- 標準的なHWでクラスターを構成する、Scale-Out型アーキテクチャー
- ペタバイト級に対応する高いScalability
- Cloud Infrastructure, CDN, Data Lakeなど新しいワークロードに適したソフトウェアデザイン
- Self-serviceのストレージ管理を実現するManagement APIの提供
RADOS
RADOSとはReliable Autonomous Distributed Object Storeの頭字語です。RADOSはCephの核となるオブジェクトストアで、Cephに書かれるデータは全てオブジェクトの形式でRADOSに格納されます。
RADOSを構成する要素として、OSDとMONとMGRがあります。
OSD
OSDはObject Storage Deviceの頭字語です。ざっくり言うと、Cephクラスタの保存媒体であるデバイスを抽象化した姿です。
- OSD = device(HDD, SDD) + ロケーションを管理するシステム + read/writeのリクエストを受ける daemon
- ロケーションを管理するシステムは、FileStoreの場合はファイルシステム、BlueStoreの場合はrocksDB
- 1デバイス = 1OSDの割り当てが基本。NVMeなど高性能のFlashデバイスの場合は1デバイス = 複数OSDに割り当てることもある
- クラスタ内で一意の通しIDと名前を持つ
MON
MONはMonitorです。ざっくり言うと、Cephクラスタのライフセーバーみたいな役割です。平常時は正直それほど働かないのであんまり目立たないんですが、超重用な役割なんです。
- MONはクラスタを常時監視し、“Cluster Map”というクラスタ全体の状態を把握する情報を管理する
- 障害や拡張によるクラスタトポロジーの変化を察知し、望ましい姿への復帰(下がった冗長性の復旧など)を司る
- クラスタに通常複数存在し、分散したMON同士で単一のクラスタ状態を共有するためにPaxosアルゴリズムによる分散合意形成を行う
- クラスターには3つ以上の奇数(2N+1)個のMONが必要で、N個までMONがDownしても合意形成が可能
- クライアントの認証も行う
MGR
MGRはManagerです。ざっくり言うと、矢吹丈に対する丹下段平みたいにMONと常に一緒にいてサポートします。
あとCephFS使う場合はMDSというものも出てきますが今は置いときます。
Pool と Placement Group(PG)
PoolとPlacement Group(PG)はRADOSの中でも重要な概念です。
Pool
Poolは論理的なデータの保存領域です。CephクライアントはPoolに対してデータをRead/Writeします。
PoolはObject, Block, Fileのクライアントの利用用途によらず共通で利用することができますが、用途が変われば冗長性や性能等の要件が異なることが多いので、基本的には用途ごとにPoolは分けるのが普通です。
Poolを作成する時には"CRUSH rule"を指定します。ruleを指定しなければ、Cephのconfigファイル(ceph.conf)に記載されるデフォルトのruleが適用されます。
Replicated Pool と Erasure Coded Pool
指定したCRUSH ruleに従ってPoolのPGが作成されますが、ruleの書き方によってPoolは2つのタイプに大別されます。
Replicated Pool
Erasure Coded(EC) Pool
BlockやFileで使う場合はReplicated Poolの方がレスポンスがいいのでよいでしょう。Objectで使う場合はEC Poolの方が容量効率が高いのでいいかもしれません。
Placement Group(PG)
前述の通り、PGはPool作成時に自動的に作成される、CRUSH ruleに沿って構成されるOSDのグループです。
例えば3x Replicated Poolを作った場合、1つのPGには3つのOSDがランダムに割り当たります。Pool作成時にpg-numで指定した数だけ、このPGが作られます。
通常PGはOSDよりも多く作られ、1つのOSDは複数のPGで重複して割り当てられます。1OSDは50〜100くらいのPGに割り当たるようにPool作成時にpg-numで調節するのが一般的な構成では良いようですが、OSDの数によって変わるのでPGCalcでシミュレートするのがよいです。
CephクライアントがPoolにWriteすると、データは既定のサイズのオブジェクトにストライプされ、各ストライプでCRUSHアルゴリズムによって1つのPGが選択され、そのPGが持つ複数のOSDに書き込まれます。
PGのOSDには順序が存在します。例えば、[0,1,2]と[2,1,0]は、同じOSDの割り当てながら順序が違うため異なるPGとなります。
先頭のPrimary OSDがそのPGの代表として(ストライプされた)オブジェクトのRead/Write処理を行います。Read/Write時の動作はPoolのタイプによって異なります。
また、PGはOSDの数に対して結構多く作られるので、全く同じOSD順序のPGが2つ以上作られることが普通にあります。
ですが、これ自身は全く問題ありません。別にどちらのPGが使われてもOSDに分散されることには違いないのですから。
それだとデバイスの利用率に偏りが出るのでは?という疑問が湧いてきますが、そもそもRADOSは、
「全部の玉のutilizationをきれいに揃える必要ないよ、何百何千発にもスケールした時そんな管理してたらオーバーヘッドなだけでしょ?ゆるく揃ってればいいじゃん。目立つ偏りがあったらアラート上げるからrebalanceかけるんだよ」
というコンセプトで作られています。なのでOSDの割り当てで発生する偏りは構わないのです。
またrebalanceはSDSで一番問題になりやすい強敵ですが、rebalanceの問題は『きれいに利用率を揃えようとして必要以上にデータの移動が発生し、結果ネットワークトラフィックが重い時間が長くなること』です。Cephではゆるく揃えばそれでいいので、必要最小限のデータ移動で済むようになってます。
CRUSH rule
CRUSH ruleは早い話が、PGに割り当てるOSDの決め方のルールです。
例えばruleなく1つのPGに3つのOSDをランダムに割り当てると、同一ノード上の3つのOSDを選択する可能性があります。これだとそのノードが壊れた時データロスになります。
しかし『ノードから1個ずつOSDを選択する』というruleを書いておけば、そのようにOSDが選択されるので、3つのノードにレプリカされることになります。
CRUSH ruleを駆使することで、任意のfailure domainでデータを冗長化することができます。
まとめ
今日はCephっていうかRADOSを説明しました。RADOSはとても良くできた仕組み(特にCRUSHが)で、うつぼはCephと出会ってこの仕組みに目から鱗が落ち、Cephが大好きになりました。
みなさんもCephが大好きになってくれたらうれしいです。(小並感)
BGMは回レ!雪月花でした。