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

Cephの紹介

f:id:ututaq:20191125022735p:plain

この記事はRookだらけの Advent Calendar 2019 2日目の記事です。

Rookとは少し離れますが、Cephの説明をしたいと思います。

Ceph

Cephの特徴はググればたくさん出てくるので、詳しく知りたい人はググって下さい。ざっくり簡単に書きます。

RADOS

RADOSとはReliable Autonomous Distributed Object Storeの頭字語です。RADOSはCephの核となるオブジェクトストアで、Cephに書かれるデータは全てオブジェクトの形式でRADOSに格納されます。
RADOSを構成する要素として、OSDとMONとMGRがあります。

f:id:ututaq:20191201232106p:plain

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と常に一緒にいてサポートします。

  • CephのGUI(Dashboard)を提供する
  • Prometheus,Zabbixなど外部の管理/監視ツールへのAPIを提供する
  • 補助的にクラスタ監視の役割

あとCephFS使う場合はMDSというものも出てきますが今は置いときます。

Pool と Placement Group(PG)

PoolとPlacement Group(PG)はRADOSの中でも重要な概念です。

Pool

f:id:ututaq:20191201235421p:plain

Poolは論理的なデータの保存領域です。CephクライアントはPoolに対してデータをRead/Writeします。
PoolはObject, Block, Fileのクライアントの利用用途によらず共通で利用することができますが、用途が変われば冗長性や性能等の要件が異なることが多いので、基本的には用途ごとにPoolは分けるのが普通です。
Poolを作成する時には"CRUSH rule"を指定します。ruleを指定しなければ、Cephのconfigファイル(ceph.conf)に記載されるデフォルトのruleが適用されます。

Replicated Pool と Erasure Coded Pool

f:id:ututaq:20191201235425p:plain

指定したCRUSH ruleに従ってPoolのPGが作成されますが、ruleの書き方によってPoolは2つのタイプに大別されます。

  • Replicated Pool

    • オブジェクトを複製して冗長化
    • 容量効率は低いがI/O性能とリカバリの早さにはEC Poolより優れる
    • 一般的によく利用される標準のタイプ
  • Erasure Coded(EC) Pool

    • Erasure Codingの仕組みで冗長化
    • I/O性能とリカバリはReplicated Poolに劣るが容量効率は高い
    • 大容量が必要なケースで利用される

BlockやFileで使う場合はReplicated Poolの方がレスポンスがいいのでよいでしょう。Objectで使う場合はEC Poolの方が容量効率が高いのでいいかもしれません。

Placement Group(PG)

f:id:ututaq:20191202005121p:plain

前述の通り、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 PGCalc - Ceph

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のタイプによって異なります。

f:id:ututaq:20191202005212p:plain f:id:ututaq:20191202005233p:plain

また、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は回レ!雪月花でした。