第2章 CRUSH 管理
CRUSH (Controlled Replication Under Scalable Hashing) アルゴリズムは、コンピューティングデータストレージの場所によるデータの格納および取得方法を決定します。
十分な高度な技術は、マジックなものと主導しているものと言えます。 | ||
-- Arthur C. Clarke |
2.1. CRUSH の概要
ストレージクラスターの CRUSH マップは、CRUSH 階層内のデバイスの場所と、Ceph がデータをどのように保管するかを決定する各階層のルールを記述します。
CRUSH マップには、最低でもノードの階層が 1 つ含まれ、残されます。Ceph の「buckets」という階層のノードは、その種別で定義されるストレージの場所の集約です。たとえば、行、ラック、シャーシ、ホスト、およびデバイスなどがあります。階層の各リーフは、ストレージデバイスの一覧におけるストレージデバイスの 1 つを基本的に構成します。リーフは常に 1 つのノードまたは「bucket」に含まれます。 CRUSH マップには、CRUSH ストアとデータの取得方法を決定するルールの一覧もあります。
OSD をクラスターに追加する際に、ストレージデバイスが CRUSH マップに追加されます。
CRUSH アルゴリズムは、デバイスごとの加重値に従ってストレージデバイス間でデータオブジェクトを分散します。これは、統一された確率分を分散します。CRUSH は、管理者が定義する階層のクラスターに応じて、オブジェクトとそのレプリカ、または消去したチャンクを分散します。CRUSH マップは、利用可能なストレージデバイスと、ルールにそれらを含む論理バケット、およびルールを使用する各プールで、それぞれを表します。
障害ドメインまたはパフォーマンスドメイン全体で OSD に配置グループをマップするために、CRUSH マップはバケットタイプの階層的な一覧を定義します。これは、生成された CRUSH マップの types
の下にあります。バケット階層を作成する目的は、リーフノードを障害ドメインまたはパフォーマンスドメインか、またはその両方で分離することです。障害ドメインには、ホスト、シャーシ、ラック、電源分散ユニット、Pod、行、部屋、およびデータセンターが含まれます。パフォーマンスドメインには、特定の設定の障害ドメインおよび OSD が含まれます。たとえば、SSD ジャーナル、SATA ドライブなどを使用した SSD、SAS ドライブなどです。RHCS 3 では、デバイスは hdd
、ssd
、nvme
などの class
の概念を持ち、デバイスのクラスを使用して CRUSH 階層をより迅速にビルドします。
OSD を表すリーフノードを除き、階層の残りの部分は任意となり、デフォルトタイプが要求に適さない場合、独自のニーズに応じて定義することができます。CRUSH のマップのバケットタイプを組織のハードウェアの命名規則に適合し、物理ハードウェア名を反映するインスタンス名を使用することが推奨されます。命名プラクティスを使用すると、OSD または他のハードウェアの誤作動時に、クラスターの管理と問題のトラブルシューティングを容易にし、管理者がホストまたは他のハードウェアへのリモートアクセスまたは物理的なアクセスが必要な場合に役立ちます。
以下の例では、バケット階層には 4 つのリーフバケット (osd 1-4
)、ノードバケット (host 1-2
)、および 1 つのラックノード (rack 1
) があります。
リーフノードは、CRUSH マップの開始時に devices
一覧に宣言されたストレージデバイスを反映するため、それらをバケットインスタンスとして宣言する必要はありません。階層内の 2 番目のバケットタイプは、通常デバイスを集約し、通常はストレージメディアが含まれるコンピューターで、管理者が好む "node"、"computer"、"server"、"host"、"machine"、"machine" などの用語を使用します。高密度の高い環境では、カードごとおよびシャーシごとに複数のホスト/ノードを確認することが一般的です。カードおよびシャーシの不具合も考慮に入れるようにしてください。たとえば、ノードに障害が発生した場合に、カードやシャーシを引き抜かなければならないようなことになると、非常に多くのホスト/ノードと OSD がダウンすることがあります。
バケットインスタンスを宣言する場合は、その型を指定し、一意の名前を文字列として指定し、負の整数として表現される任意の一意の ID を割り当て、アイテムの合計容量または機能に対する重みを指定し、straw
などのバケットアルゴリズムを指定します。また、通常はハッシュアルゴリズム rjenkins1
を反映した 0
となるハッシュを指定します。バケットには 1 つ以上の項目を指定できます。この項目は、ノードバケットで構成されるか、そのままになります。項目は、項目の相対的な重みを反映する重みを指定できます。
2.1.1. データの動的配置
Ceph クライアントおよび Ceph OSD はどちらも CRUSH マップと CRUSH アルゴリズムを使用します。
- Ceph Clients: CRUSH マップを Ceph クライアントに配布することにより、CRUSH は Ceph クライアントが OSD に直接通信できるようにします。つまり、Ceph クライアントは、単一障害点、パフォーマンスのボトルネック、集中ルックアップサーバーにおける接続制限、ストレージクラスターのスケーラビリティーへの物理的な制限などの集中オブジェクトルックアップテーブルを回避します。
- Ceph OSD: CRUSH マップを Ceph OSD に分散することにより、Ceph は OSD を変換してレプリケーション、バックフィル、およびリカバリーを処理します。つまり、Ceph OSD は Ceph クライアントの代わりにオブジェクトレプリカ (または共存するチャンク) のストレージを処理することを意味します。また、Ceph OSD はクラスター (バックフィル) をクラスターを再分散し、障害から動的に回復するのに十分なクラスターについて把握できることを意味します。
2.1.2. 障害ドメインの確立
複数のオブジェクトレプリカまたは M
イレイジャーコーディングチャンクを使用するとデータの損失を防ぐことができますが、高可用性に対応するには十分ではありません。Ceph Storage クラスターの基礎となる物理組織を反映することで、CRUSH は、関連するデバイスの障害についてのアドレス指定元的なソースをモデル化できます。クラスターのトポロジーをクラスターマップにエンコードすることで、CRUSH 配置ポリシーは別々の障害ドメインにわたって、オブジェクトレプリカまたはイレイジャーコーディングチャンクを別々に使用できます。また、必要な疑似ランダム分散も依然として維持できます。たとえば、同時障害の可能性に対応するには、異なるシェルフ、ラック、電源、コントローラーまたは物理的な場所を使用するデバイス上または消去するチャンクがデバイスにあることが望ましい場合があります。これは、データ損失を回避し、クラスターが動作が低下した状態で動作できるようにします。
2.1.3. パフォーマンスドメインの確立
CRUSH マップは複数の階層をサポートし、ハードウェアパフォーマンスプロファイルのタイプを別のタイプから分離できます。たとえば、CRUSH はハードディスクドライブと SSD に別の階層を 1 つ作成できます。パフォーマンスドメイン: ベースとなるハードウェアのパフォーマンスプロファイルを把握する階層は、さまざまなパフォーマンス特性をサポートする必要があるため、注目されています。運用上、それらは複数の root
タイプバケットを持つ CRUSH マップです。ユースケースの例を以下に示します。
- 仮想マシン: OpenStack、CloudStack、ProxMox、OpenNebula などのクラウドプラットフォームのバックエンドとして機能する Ceph ホストは、ジャーナリング用に高性能 SSD がパーティション化されている SAS ドライブ上の XFS など、最も安定したファイルシステムを使用する傾向があります。XFS はジャーナルと書き込みを同時に行わないためです。一貫したパフォーマンスプロファイルを維持するために、このようなユースケースでは、同じハードウェアを CRUSH 階層に集約する必要があります。
- Object Storage: S3 および Swift インターフェースのオブジェクトストレージバックエンドとして機能する Ceph ホストは、仮想マシンに適さない SATA ドライブなど、より安価なストレージメディアを利用する場合があります。また、オブジェクトストレージのギガバイトあたりのコストを軽減しつつ、クラウドプラットフォームでボリュームやイメージを保管するより高性能なストレージホストとより安価なストレージホストを分離することができます。HTTP はオブジェクトストレージシステムでボトルネックとなる傾向があります。
- コールドストレージ: コールドストレージ用に設計されたシステム (アクセス頻度が低いデータや、パフォーマンス要件が緩和されたデータの取得) では、より安価なストレージメディアやイレイジャーコーディングを利用できます。ただし、イレイジャーコーディングには、追加の RAM および CPU が必要になることがあり、そのため、オブジェクトストレージまたは仮想マシンに使用されるホストからの RAM および CPU 要件とは異なります。
-
SSD でバックアップされるプール: SSD は高価ですが、ハードドライブよりも大きな利点があります。SSD にはシーク時間がなく、合計スループットが提供されます。ジャーナリングに SSD を使用することに加え、クラスターは、SSD のバックエンドプールをサポートできます。一般的なユースケースには、高パフォーマンス SSD プールが含まれます。たとえば、Ceph Object Gateway の
.rgw.buckets.index
プールを SATA ドライブではなく SSD にマッピングすることができます。
RHCS 3 以降のリリースでは、CRUSH マップはデバイス class
の概念をサポートします。Ceph はストレージデバイスの要素を検出し、自動的に hdd
、ssd
、nvme
などのクラスを割り当てることができます。ただし、CRUSH はこれらのデフォルトに限定されません。たとえば、CRUSH の階層を使用して、異なるタイプのワークロードを区切られることもできます。たとえば、SSD は、ジャーナルまたはログ先行書き込み、バケットインデックス、または raw オブジェクトストレージに使用される場合があります。CRUSH は ssd-bucket-index
、ssd-object-storage
などの異なるデバイスクラスをサポートできるため、Ceph は異なるワークロードに同じストレージメディアを使用しないようにします。これによりパフォーマンスは予測可能で一貫性が高くなります。
2.1.3.1. RHCS 2 以降での Different Device Classes の使用
RHCS 2 以前には、デバイスクラスの概念はありません。SSD や SATA ドライブなど、RHCS 2 以前で異なるストレージクラスを使用するには、SSD ドライブおよび SATA ドライブを参照するプールを作成します。これらのプールに送信されるデータは、SSD ドライブおよび SATA ドライブにそれぞれ個別のルート階層を作成して分離する必要があります。CRUSH マップは SSD に 1 つの階層と SATA ドライブに 1 つの階層を定義する必要があります。SSD ドライブと SATA ドライブは同じホストまたは別のホストに存在する場合があります。
2 つの CRUSH 階層が存在したら、SSD および SATA 階層に個別のルールを作成し、適切なルールセットを使用するように対応するプールを設定します。
- 注記
-
Red Hat は、RHCS 3.0 以降のリリースでの
ruleset
の概念はサポートしていません。CRUSH ルールセットの詳細は、RHCS 2 のドキュメントを参照してください。
これを行うには、CRUSH マップを変更します (変更するには CRUSH マップを逆コンパイルします。詳細は「CRUSH マップのでコンパイル」セクションを参照してください)。CRUSH アルゴリズムがオブジェクトを保存する 2 つの異なるルートポイントまたはエントリーポイントを作成します。SSD ディスクには 1 つのルートと SATA ディスク用のルートが 1 つあります。以下の例には、各ホストに 2 つの SATA ディスクと 2 つの SSD ディスク、および合計 3 つのホストがあります。これにより、CRUSH は 2 つの異なるプラットフォームがあると判断します。
CRUSH マップの例:
## # OSD SATA DECLARATION ## host ceph-osd2-sata { id -2 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.0 weight 1.000 item osd.3 weight 1.000 } host ceph-osd1-sata { id -3 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.2 weight 1.000 item osd.5 weight 1.000 } host ceph-osd0-sata { id -4 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.1 weight 1.000 item osd.4 weight 1.000 } ## # OSD SSD DECLARATION ## host ceph-osd2-ssd { id -22 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.6 weight 1.000 item osd.9 weight 1.000 } host ceph-osd1-ssd { id -23 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.8 weight 1.000 item osd.11 weight 1.000 } host ceph-osd0-ssd { id -24 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.7 weight 1.000 item osd.10 weight 1.000 }
OSD を含む 2 つのルートを作成します。
## # SATA ROOT DECLARATION ## root sata { id -1 # do not change unnecessarily # weight 6.000 alg straw hash 0 # rjenkins1 item ceph-osd2-sata weight 2.000 item ceph-osd1-sata weight 2.000 item ceph-osd0-sata weight 2.000 } ## # SATA ROOT DECLARATION ## root ssd { id -21 # do not change unnecessarily # weight 6.000 alg straw hash 0 # rjenkins1 item ceph-osd2-ssd weight 2.000 item ceph-osd1-ssd weight 2.000 item ceph-osd0-ssd weight 2.000 }
SSD 用に新しいルールを 2 つ作成します。
## # SSD RULE DECLARATION ## # rules rule ssd { ruleset 0 type replicated min_size 1 max_size 10 step take ssd step chooseleaf firstn 0 type host step emit } ## # SATA RULE DECLARATION ## rule sata { ruleset 1 type replicated min_size 1 max_size 10 step take sata step chooseleaf firstn 0 type host step emit }
新しいマップをコンパイルし、注入します。
$ crushtool -c lamap.txt -o lamap.coloc $ sudo ceph osd setcrushmap -i lamap.coloc
結果を確認します。
$ sudo ceph osd tree # id weight type name up/down reweight -21 12 root ssd -22 2 host ceph-osd2-ssd 6 1 osd.6 up 1 9 1 osd.9 up 1 -23 2 host ceph-osd1-ssd 8 1 osd.8 up 1 11 1 osd.11 up 1 -24 2 host ceph-osd0-ssd 7 1 osd.7 up 1 10 1 osd.10 up 1 -1 12 root sata -2 2 host ceph-osd2-sata 0 1 osd.0 up 1 3 1 osd.3 up 1 -3 2 host ceph-osd1-sata 2 1 osd.2 up 1 5 1 osd.5 up 1 -4 2 host ceph-osd0-sata 1 1 osd.1 up 1 4 1 osd.4 up 1
プールで動作するようになりました。
プールを作成します。
プールの
ssd
:root@ceph-mon0:~# ceph osd pool create ssd 128 128
プールの
sata
:root@ceph-mon0:~# ceph osd pool create sata 128 128
ルールをプールに割り当てます。
プール 8 crush_ruleset を 0 に設定します。
root@ceph-mon0:~# ceph osd pool set ssd crush_ruleset 0
プール 9 crush_ruleset を 1 に設定します。
root@ceph-mon0:~# ceph osd pool set sata crush_ruleset 1
ceph osd dump
の結果:pool 8 'ssd' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 128 pgp_num 128 last_change 116 flags hashpspool stripe_width 0 pool 9 'sata' replicated size 2 min_size 1 crush_ruleset 1 object_hash rjenkins pg_num 128 pgp_num 128 last_change 117 flags hashpspool stripe_width 0
サービスの再起動時に OSD がデフォルトの CRUSH の場所に戻されないようにするには、osd crush update on start = false
を使用して、デーモンの開始時に CRUSH マップの更新を無効にします。
2.1.3.2. RHCS 3 以降での Different Device Classes の使用
RHCS 3 でパフォーマンスドメインを作成するには、デバイスクラスと単一の CRUSH 階層を使用します。CLI を使用して RHCS 2 と同様に、OSD を CRUSH 階層に追加するだけです。次に、以下を実行します。
各デバイスにクラスを追加します。以下に例を示します。
# ceph osd crush set-device-class <class> <osdId> [<osdId>] # ceph osd crush set-device-class hdd osd.0 osd.1 osd.4 osd.5 # ceph osd crush set-device-class ssd osd.2 osd.3 osd.6 osd.7
次に、デバイスを使用するルールを作成します。
# ceph osd crush rule create-replicated <rule-name> <root> <failure-domain-type> <class> # ceph osd crush rule create-replicated cold default host hdd # ceph osd crush rule create-replicated hot default host ssd
最後に、ルールを使用するようにプールを設定します。
ceph osd pool set <poolname> crush_rule <rule-name> ceph osd pool set cold_tier crush_rule cold ceph osd pool set hot_tier crush_rule hot
RHCS 3 以降では、CRUSH マップを手動で編集する必要はありません。