17 保存データの管理 #
CRUSHアルゴリズムは、データの保存場所を計算することによって、データの保存と取得の方法を決定します。CRUSHにより、Cephクライアントは、中央サーバやブローカ経由ではなく直接OSDと通信できるようになります。アルゴリズムで決定されるデータの保存と取得の方法を使用することで、Cephは、SPOF (single point of failure)、パフォーマンスのボトルネック、およびスケーラビリティの物理的な制限を解消します。
CRUSHはクラスタのマップを必要とし、そのCRUSHマップを使用して、クラスタ全体に均等に分散したデータを擬似ランダムにOSDに保存および取得します。
CRUSHマップには、OSDのリスト、デバイスを物理的な場所に集約するための「バケット」のリスト、およびCephクラスタのプール内でデータをどのように複製するかをCRUSHに指示するルールのリストが含まれます。インストールの基礎になっている物理的な組織を反映することで、CRUSHは、相関するデバイス障害の潜在的な原因をモデル化し、これによってその原因に対応できます。原因としては、物理的な距離の近さ、共有電源、共有ネットワークなどが代表的です。この情報をクラスタマップにエンコードすることにより、CRUSHの配置ポリシーは、オブジェクトのレプリカを異なる障害ドメインに分離しながら、必要な分散を維持できます。たとえば、発生する可能性がある同時障害に対応するため、データレプリカを、異なるシェルフ、ラック、電源、コントローラ、または物理的な場所を使用するデバイスに配置することが望ましい場合があります。
Cephクラスタの展開後、デフォルトのCRUSHマップが生成されます。Cephサンドボックス環境にはこれで十分です。ただし、大規模なデータクラスタを展開する場合は、カスタムCRUSHマップの作成を積極的に検討する必要があります。カスタムCRUSHマップは、Cephクラスタの管理、パフォーマンスの向上、およびデータの安全性の確保に役立つためです。
たとえば、OSDがダウンしてオンサイトでのサポートやハードウェアの交換が必要になった場合、CRUSHマップがあれば、ホストの物理的なデータセンター、ルーム、列、およびラックの場所を容易に特定できます。
同様に、障害の特定の迅速化にも役立つことがあります。たとえば、特定のラックのOSDすべてが同時にダウンした場合、OSD自体の障害ではなく、ネットワークスイッチ、あるいはラックまたはネットワークスイッチの電源の障害であることがあります。
カスタムCRUSHマップは、障害が発生したホストに関連付けられた配置グループ(17.4項 「配置グループ」を参照)が機能低下状態になった場合に、Cephによってデータの冗長コピーが保存される物理的な場所を特定するのにも役立ちます。
CRUSHマップには主なセクションが3つあります。
17.1 OSDデバイス #
配置グループをOSDにマップするため、CRUSHマップにはOSDデバイスのリスト(OSDデーモンの名前)が必要です。デバイスのリストはCRUSHマップの先頭に記述されます。
#devices device NUM osd.OSD_NAME class CLASS_NAME
以下に例を示します。
#devices device 0 osd.0 class hdd device 1 osd.1 class ssd device 2 osd.2 class nvme device 3 osd.3 class ssd
一般的な規則として、OSDデーモンは1つのディスクにマップされます。
17.1.1 デバイスクラス #
CRUSHマップによってデータ配置を柔軟に制御できる点は、Cephの強みの1つです。これは、クラスタの管理において最も困難な部分の1つでもあります。「デバイスクラス」を使用すると、これまで管理者が手動で行う必要があった、CRUSHマップに対して特によく行われる変更を自動化できます。
17.1.1.1 CRUSHの管理の問題 #
多くの場合、Cephクラスタは、HDD、SSD、NVMeなど複数のタイプのストレージデバイスで構築し、これらの種類を混在させる場合もあります。ここでは、このようなさまざまなタイプのストレージデバイスを「デバイスクラス」と呼びます。これは、CRUSHバケットの「タイプ」プロパティを混同しないようにするためです(たとえば、ホスト、ラック、列など。詳細については17.2項 「バケット」を参照してください)。SSDでサポートされているCeph OSDは、回転型のディスクでサポートされているものよりはるかに高速であるため、特定のワークロードに適しています。Cephを使用すると、異なるデータセットやワークロード用のRADOSプールを簡単に作成したり、これらのプールのデータ配置を制御するために異なるCRUSHルールを簡単に割り当てたりすることができます。
ただし、データを特定のデバイスクラスにのみ配置するようにCRUSHルールを設定するのは面倒です。ルールはCRUSH階層の点から見ると有効ですが、(上記のサンプル階層のように)複数のデバイスが同じホストやラックに混在する場合、これらのデバイスは混在して階層の同じサブツリーに表示されます(デフォルト)。以前のバージョンのSUSE Enterprise Storageでは、これらを手動で別個のツリーに分離するには、デバイスクラスごとに1つずつ、複数のバージョンの中間ノードを作成する必要がありました。
17.1.1.2 デバイスクラス #
Cephが提供する優れた解決策は、各OSDに「デバイスクラス」というプロパティを追加することです。デフォルトで、OSDは、Linuxカーネルによって公開されるハードウェアプロパティに基づいて、そのデバイスクラスを「hdd」、「ssd」、または「nvme」のいずれかに自動的に設定します。これらのデバイスクラスはceph osd tree
コマンド出力の新しい列でレポートされます。
cephuser@adm >
ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 83.17899 root default
-4 23.86200 host cpach
2 hdd 1.81898 osd.2 up 1.00000 1.00000
3 hdd 1.81898 osd.3 up 1.00000 1.00000
4 hdd 1.81898 osd.4 up 1.00000 1.00000
5 hdd 1.81898 osd.5 up 1.00000 1.00000
6 hdd 1.81898 osd.6 up 1.00000 1.00000
7 hdd 1.81898 osd.7 up 1.00000 1.00000
8 hdd 1.81898 osd.8 up 1.00000 1.00000
15 hdd 1.81898 osd.15 up 1.00000 1.00000
10 nvme 0.93100 osd.10 up 1.00000 1.00000
0 ssd 0.93100 osd.0 up 1.00000 1.00000
9 ssd 0.93100 osd.9 up 1.00000 1.00000
たとえば、デバイスドライバがデバイスに関する情報を/sys/block
を介して適切に公開していないためにデバイスクラスの自動検出に失敗する場合、コマンドラインからデバイスクラスを調整できます。
cephuser@adm >
ceph osd crush rm-device-class osd.2 osd.3 done removing class of osd(s): 2,3cephuser@adm >
ceph osd crush set-device-class ssd osd.2 osd.3 set osd(s) 2,3 to class 'ssd'
17.1.1.3 CRUSH配置ルールの設定 #
CRUSHルールにより、特定のデバイスクラスへの配置を制限できます。たとえば、次のコマンドを実行して、SSD上にのみデータを分散する高速な「複製」プールを作成できます。
cephuser@adm >
ceph osd crush rule create-replicated RULE_NAME ROOT FAILURE_DOMAIN_TYPE DEVICE_CLASS
以下に例を示します。
cephuser@adm >
ceph osd crush rule create-replicated fast default host ssd
「fast_pool」というプールを作成し、それを「fast」ルールに割り当てます。
cephuser@adm >
ceph osd pool create fast_pool 128 128 replicated fast
「イレージャコード」ルールを作成するプロセスはわずかに異なります。まず、目的のデバイスクラスのプロパティを含むイレージャコードプロファイルを作成します。その後、イレージャコーディングプールを作成する際にそのプロファイルを使用します。
cephuser@adm >
ceph osd erasure-code-profile set myprofile \ k=4 m=2 crush-device-class=ssd crush-failure-domain=hostcephuser@adm >
ceph osd pool create mypool 64 erasure myprofile
CRUSHマップを手動で編集してルールをカスタマイズする必要がある場合に備えて、デバイスクラスを指定できるように構文が拡張されています。たとえば、上のコマンドによって生成されたCRUSHルールは次のようになります。
rule ecpool {
id 2
type erasure
min_size 3
max_size 6
step set_chooseleaf_tries 5
step set_choose_tries 100
step take default class ssd
step chooseleaf indep 0 type host
step emit
}
ここでの重要な違いは、「take」コマンドに追加のサフィックス「class CLASS_NAME」が含まれている点です。
17.1.1.4 追加のコマンド #
CRUSHマップで使用されるデバイスクラスを一覧にするには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush class ls
[
"hdd",
"ssd"
]
既存のCRUSHルールを一覧にするには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush rule ls
replicated_rule
fast
「fast」という名前のCRUSHルールの詳細を表示するには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush rule dump fast
{
"rule_id": 1,
"rule_name": "fast",
"ruleset": 1,
"type": 1,
"min_size": 1,
"max_size": 10,
"steps": [
{
"op": "take",
"item": -21,
"item_name": "default~ssd"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
}
「ssd」クラスに属するOSDを一覧にするには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush class ls-osd ssd
0
1
17.1.1.5 古いSSDルールからデバイスクラスへの移行 #
バージョン5より前のSUSE Enterprise Storageでは、SSDなどのデバイスに適用されるルールを作成するには、CRUSHマップを手動で編集し、特殊なデバイスタイプ(SSDなど)それぞれに対して並列階層を維持する必要がありました。SUSE Enterprise Storage 5から、この処理は、デバイスクラス機能によって透過的に有効になりました。
crushtool
コマンドを使用して、古いルールと階層を新しいクラスベースのルールに変換できます。次のように複数のタイプの変換が可能です。
crushtool --reclassify-root ROOT_NAME DEVICE_CLASS
このコマンドは、以下を使用して、ROOT_NAMEの下の階層にあるものをすべて取得し、そのルートを参照するルールをすべて調整します。
take ROOT_NAME
これを代わりに以下に調整します。
take ROOT_NAME class DEVICE_CLASS
さらに、指定したクラスの「シャドウツリー」に古いIDを使用するよう、バケットの番号を再割り当てします。そのため、データの移動は発生しません。
例 17.1:crushtool --reclassify-root
#次のような既存のルールについて考えてみてください。
rule replicated_ruleset { id 0 type replicated min_size 1 max_size 10 step take default step chooseleaf firstn 0 type rack step emit }
ルート「default」をクラス「hdd」として再分類した場合、このルールは次のようになります。
rule replicated_ruleset { id 0 type replicated min_size 1 max_size 10 step take default class hdd step chooseleaf firstn 0 type rack step emit }
crushtool --set-subtree-class BUCKET_NAME DEVICE_CLASS
この方法は、BUCKET_NAMEをルートとするサブツリー内にあるすべてのデバイスに、指定したデバイスクラスのマークを付けます。
--set-subtree-class
は通常、--reclassify-root
オプションと組み合わせて使用し、そのルートにあるすべてのデバイスに正しいクラスのラベルが付けられるようにします。ただし、これらのデバイスによっては意図的に異なるクラスを使用しているものがあるため、再度ラベルを付けたくない場合があります。このような場合は、--set-subtree-class
オプションを除外してください。このような再マッピングは完全ではないことに注意してください。以前のルールは複数のクラスのデバイスにわたって分散されますが、調整されたルールは指定したデバイスクラスのデバイスにのみマップされるためです。crushtool --reclassify-bucket MATCH_PATTERN DEVICE_CLASS DEFAULT_PATTERN
この方法では、並列タイプに固有の階層を通常の階層にマージできます。たとえば、多くのユーザが次のようなCRUSHマップを使用しています。
例 17.2:crushtool --reclassify-bucket
#host node1 { id -2 # do not change unnecessarily # weight 109.152 alg straw hash 0 # rjenkins1 item osd.0 weight 9.096 item osd.1 weight 9.096 item osd.2 weight 9.096 item osd.3 weight 9.096 item osd.4 weight 9.096 item osd.5 weight 9.096 [...] } host node1-ssd { id -10 # do not change unnecessarily # weight 2.000 alg straw hash 0 # rjenkins1 item osd.80 weight 2.000 [...] } root default { id -1 # do not change unnecessarily alg straw hash 0 # rjenkins1 item node1 weight 110.967 [...] } root ssd { id -18 # do not change unnecessarily # weight 16.000 alg straw hash 0 # rjenkins1 item node1-ssd weight 2.000 [...] }
この機能は、指定したパターンに一致する各バケットを再分類します。パターンは
%suffix
またはprefix%
のようになります。上の例では、パターン%-ssd
を使用します。一致した各バケットに対し、ワイルドカード「%」に一致する、名前の残りの部分にベースバケットが指定されます。一致したバケットのすべてのデバイスに指定したデバイスクラスのラベルが付けられ、デバイスがベースバケットに移動されます。ベースバケットが存在しない場合(たとえば、「node12-ssd」は存在するものの「node12」は存在しない場合)、指定したデフォルトの親バケットの下にベースバケットが作成されてリンクされます。古いバケットIDは新しいシャドウバケット用に保持されるため、データの移動は行われません。古いバケットを参照するtake
ステップが含まれるルールが調整されます。crushtool --reclassify-bucket BUCKET_NAME DEVICE_CLASS BASE_BUCKET
--reclassify-bucket
オプションをワイルドカードなしで使用して、単一のバケットをマップできます。たとえば、前の例では、「ssd」バケットをデフォルトのバケットにマッピングしたいと考えています。上のフラグメントで構成されるマップを変換する最後のコマンドは、次のとおりです。
cephuser@adm >
ceph osd getcrushmap -o originalcephuser@adm >
crushtool -i original --reclassify \ --set-subtree-class default hdd \ --reclassify-root default hdd \ --reclassify-bucket %-ssd ssd default \ --reclassify-bucket ssd ssd default \ -o adjusted正しく変換されたことを確認するために、
--compare
オプションがあります。このオプションは、CRUSHマップへの大量の入力サンプルをテストし、同じ結果が返されるかどうかを比較するものです。これらの入力は、--test
に適用されるオプションと同じオプションで制御します。上の例では、コマンドは次のようになります。cephuser@adm >
crushtool -i original --compare adjusted rule 0 had 0/10240 mismatched mappings (0) rule 1 had 0/10240 mismatched mappings (0) maps appear equivalentヒント違いがあった場合は、再マップされる入力の比率がかっこ内に表示されます。
調整されたCRUSHマップに問題がなければ、マップをクラスタに適用できます。
cephuser@adm >
ceph osd setcrushmap -i adjusted
17.1.1.6 詳細の参照先 #
CRUSHマップの詳細については、17.5項 「CRUSHマップの操作」を参照してください。
Cephプールの一般的な詳細については、第18章 「ストレージプールの管理」を参照してください。
イレージャコーディングプールの詳細については、第19章 「イレージャコーディングプール」を参照してください。
17.2 バケット #
CRUSHマップにはOSDのリストが含まれており、これをツリー構造のバケット配置に編成してデバイスを物理的な場所に集約できます。個々のOSDはツリーの葉にあたります。
0 |
osd |
特定のデバイスまたはOSD ( |
1 |
ホスト |
1つ以上のOSDを含むホストの名前。 |
2 |
シャーシ |
ラック内のどのシャーシに |
3 |
ラック |
コンピュータラック。デフォルトは |
4 |
列 |
一連のラックの列。 |
5 |
pdu |
「Power Distribution Unit」(配電ユニット)の略語。 |
6 |
ポッド |
「Point of Delivery」の略語。ここでは、ひとかたまりのPDUやラック列を指します。 |
7 |
ルーム |
ラック列が設置されている部屋。 |
8 |
データセンター |
1つ以上のルームを含む、物理的なデータセンター。 |
9 |
地域 |
世界の地理的地域(たとえば、NAM、LAM、EMEA、APACなど)。 |
10 |
root |
OSDバケットツリーのルートノード(通常は、 |
既存のタイプを変更して独自のバケットタイプを作成できます。
Cephの展開ツールは、各ホストのバケットと「default」という名前のrootが含まれるCRUSHマップを生成します。これは、デフォルトのrbd
プールで役立ちます。残りのバケットタイプは、ノード/バケットの物理的な場所の情報を保存するための手段を提供します。OSD、ホスト、またはネットワークハードウェアが正常に機能しておらず、管理者が物理的なハードウェアにアクセスする必要がある場合、これによってクラスタ管理が大幅に容易になります。
バケットには、タイプ、固有の名前(文字列)、負の整数で表される固有のID、項目の合計容量/機能を基準にした相対的な重み、バケットアルゴリズム(デフォルトはstraw2
)、およびハッシュ(デフォルトは0
で、CRUSHハッシュrjenkins1
を反映)が含まれます。1つのバケットには1つ以上の項目を含めることができます。項目は他のバケットやOSDで構成できます。また、項目には、その項目の相対的な重みを反映した重みを設定できます。
[bucket-type] [bucket-name] { id [a unique negative numeric ID] weight [the relative capacity/capability of the item(s)] alg [the bucket type: uniform | list | tree | straw2 | straw ] hash [the hash type: 0 by default] item [item-name] weight [weight] }
次の例は、バケットを使用して、プールと、データセンター、ルーム、ラック、列などの物理的な場所をどのように集約できるかを示しています。
host ceph-osd-server-1 { id -17 alg straw2 hash 0 item osd.0 weight 0.546 item osd.1 weight 0.546 } row rack-1-row-1 { id -16 alg straw2 hash 0 item ceph-osd-server-1 weight 2.00 } rack rack-3 { id -15 alg straw2 hash 0 item rack-3-row-1 weight 2.00 item rack-3-row-2 weight 2.00 item rack-3-row-3 weight 2.00 item rack-3-row-4 weight 2.00 item rack-3-row-5 weight 2.00 } rack rack-2 { id -14 alg straw2 hash 0 item rack-2-row-1 weight 2.00 item rack-2-row-2 weight 2.00 item rack-2-row-3 weight 2.00 item rack-2-row-4 weight 2.00 item rack-2-row-5 weight 2.00 } rack rack-1 { id -13 alg straw2 hash 0 item rack-1-row-1 weight 2.00 item rack-1-row-2 weight 2.00 item rack-1-row-3 weight 2.00 item rack-1-row-4 weight 2.00 item rack-1-row-5 weight 2.00 } room server-room-1 { id -12 alg straw2 hash 0 item rack-1 weight 10.00 item rack-2 weight 10.00 item rack-3 weight 10.00 } datacenter dc-1 { id -11 alg straw2 hash 0 item server-room-1 weight 30.00 item server-room-2 weight 30.00 } root data { id -10 alg straw2 hash 0 item dc-1 weight 60.00 item dc-2 weight 60.00 }
17.3 ルールセット #
CRUSHマップは、プールのデータ配置を決定するルールである「CRUSHルール」の概念をサポートしています。大規模クラスタでは、ほとんどの場合、プールを大量に作成し、各プールが専用のCRUSHルールセットとルールを持つようにします。デフォルトのCRUSHマップには、デフォルトのルート用のルールがあります。ルートやルールがさらに必要な場合は、後で作成する必要があります。作成しない場合、新しいプールを作成するときに自動的に作成されます。
ほとんどの場合、デフォルトのルールを変更する必要はありません。新しいプールを作成する場合、そのデフォルトのルールセットは0です。
ルールは次の形式を取ります。
rule rulename { ruleset ruleset type type min_size min-size max_size max-size step step }
- ruleset
整数。ルールを、ルールのセットに属しているものとして分類します。プールでルールセットを設定することによって有効にします。このオプションは必須です。デフォルトは
0
です。- type
文字列。「複製」プールまたは「イレージャ」コーディングプールのいずれかのルールを記述します。このオプションは必須です。デフォルトは
replicated
です。- min_size
整数。プールグループが作成するレプリカがこの数より少ない場合、CRUSHはこのルールを選択しません。このオプションは必須です。デフォルトは
2
です。- max_size
整数。プールグループが作成するレプリカがこの数より多い場合、CRUSHはこのルールを選択しません。このオプションは必須です。デフォルトは
10
です。- step take bucket
名前で指定したバケットを取ります。ツリーの下方へ反復処理を開始します。このオプションは必須です。ツリー全体の反復処理の詳細については、17.3.1項 「ノードツリーの反復処理」を参照してください。
- step targetmodenum type bucket-type
targetは
choose
またはchooseleaf
のいずれかにできます。choose
に設定すると、大量のバケットが選択されます。chooseleaf
は、バケットセット内の各バケットのサブツリーからOSD (リーフノード)を直接選択します。modeは
firstn
またはindep
のいずれかにできます。17.3.2項 「firstn
とindep
」を参照してください。特定のタイプのバケットの数を指定します。Nを利用可能なオプションの数とすると、num > 0 && < Nの場合、それと同じ数のバケットを選択します。num < 0の場合、N - numを意味します。num == 0の場合、N個のバケット(利用可能なものすべて)を選択します。
step take
またはstep choose
に従います。- step emit
現在の値を出力してスタックを空にします。一般的にはルールの最後で使用しますが、同じルール内の別のツリーを形成する場合にも使用できます。
step choose
に従います。
17.3.1 ノードツリーの反復処理 #
バケットで定義された構造はノードツリーと見なすことができます。このツリーのバケットがノードで、OSDがリーフに当たります。
CRUSHマップのルールは、このツリーからどのような方法でOSDを選択するかを定義します。ルールは特定のノードから処理を始めて、ツリーの下方へと反復処理を行い、OSDのセットを返します。どのブランチを選択する必要があるかを定義することはできません。その代わりに、CRUSHアルゴリズムにより、OSDのセットがレプリケーション要件を満足し、データを均等に分散するよう保証されます。
step take
bucketを使用すると、ノードツリー全体の反復処理は、指定したバケット(バケットタイプではありません)から始まります。ツリー内のすべてのブランチのOSDを返す場合は、指定したバケットがルートバケットである必要があります。そうしないと、以降の手順はサブツリーでのみ反復処理されます。
ルール定義のstep take
の後にはstep choose
エントリが1つ以上続きます。それぞれのstep choose
は、直前に選択されていた上位ノードから、定義された数のノード(またはブランチ)を選択します。
最後に、step emit
で、選択されたOSDが返されます。
step chooseleaf
は、指定したバケットのブランチからOSDを直接選択する便利な機能です。
図17.2「ツリーの例」に、step
を使用してツリー全体で反復処理を行う例を示します。次のルール定義では、オレンジ色の矢印と番号はexample1a
とexample1b
に対応し、青色はexample2
に対応します。
# orange arrows rule example1a { ruleset 0 type replicated min_size 2 max_size 10 # orange (1) step take rack1 # orange (2) step choose firstn 0 host # orange (3) step choose firstn 1 osd step emit } rule example1b { ruleset 0 type replicated min_size 2 max_size 10 # orange (1) step take rack1 # orange (2) + (3) step chooseleaf firstn 0 host step emit } # blue arrows rule example2 { ruleset 0 type replicated min_size 2 max_size 10 # blue (1) step take room1 # blue (2) step chooseleaf firstn 0 rack step emit }
17.3.2 firstn
とindep
#
CRUSHルールは、障害ノードまたはOSDの置換を定義します(17.3項 「ルールセット」を参照してください)。キーワードstep
には、パラメータとしてfirstn
またはindep
が必要です。図17.3「ノードの置換方法」に例を示します。
firstn
は、アクティブノードのリストの最後に置換ノードを追加します。障害ノードの場合、以降の正常なノードが左側に移動されて、障害ノードの隙間を埋めます。これは、「複製プール」に対するデフォルトかつ適切な方法です。2つ目のノードにはすでにすべてのデータがあるため、プライマリノードの権限をただちに引き継ぐことができるからです。
indep
は、各アクティブノードに対して修復済みの置換ノードを選択します。障害ノードを置換する際に、残りのノードの順序は変更されません。これは「イレージャコーディングプール」にとって適切です。イレージャコーディングプールでは、ノードに保存されるデータは、ノード選択時の位置によって異なります。ノードの順序が変更されると、影響を受けるノードのすべてのデータを再配置しなければなりません。
17.4 配置グループ #
Cephは、オブジェクトをPG (配置グループ)にマップします。配置グループは、オブジェクトをグループとしてOSDに配置する、論理オブジェクトプールのシャードまたはフラグメントです。配置グループにより、CephがOSDにデータを保存する際のオブジェクトごとのメタデータの量が削減されます。配置グループの数が多いほど(たとえば、OSDあたり100など)、バランスが向上します。
17.4.1 配置グループの使用 #
PG (配置グループ)は複数のオブジェクトを1つのプール内に集約します。この主な理由は、オブジェクトごとにオブジェクトの配置とメタデータを追跡すると、計算コストが高くなるためです。たとえば、何百万ものオブジェクトが存在するシステムでは、その各オブジェクトの配置を直接追跡することはできません。
Cephクライアントは、オブジェクトが属する配置グループを計算します。このために、オブジェクトIDをハッシュし、定義されたプール内のPGの数と、プールのIDに基づいて操作を適用します。
配置グループ内のオブジェクトのコンテンツは、一連のOSDに保存されます。たとえば、サイズが2の複製プールでは、各配置グループは次のように2つのOSDにオブジェクトを保存します。
OSD #2に障害が発生した場合、別のOSDが配置グループ#1に割り当てられ、OSD #1内にあるすべてのオブジェクトのコピーで埋められます。プールサイズを2から3に変更すると、追加のOSDが配置グループに割り当てられ、配置グループ内にあるすべてのオブジェクトのコピーを受け取ります。
配置グループはOSDを所有するのではなく、同じプール(他のプールの場合もあり)の他の配置グループとOSDを共有するものです。OSD #2に障害が発生した場合、配置グループ#2は、OSD #3を使用してオブジェクトのコピーを復元する必要もあります。
配置グループの数が増えると、新しい配置グループにOSDが割り当てられます。CRUSH機能の結果も変化し、以前の配置グループの一部のオブジェクトは新しい配置グループにコピーされ、古い配置グループから削除されます。
17.4.2 PG_NUMの値の決定 #
Ceph Nautilus (v14.x)以降はCeph Managerのpg_autoscaler
モジュールを使用することで、必要に応じて配置グループを自動拡張できます。この機能を有効にしたい場合は、Section 8.1.1.1, “Default PG and PGP counts”を参照してください。
新しいプールを作成するときに、PG_NUMの値を従来通り手動で選択することも可能です。
#
ceph osd pool create POOL_NAME PG_NUM
PG_NUMを自動的に計算することはできません。次に、クラスタ内のOSDの数に応じた、一般的に使用される値をいくつか示します。
- OSDが5未満の場合:
PG_NUMを128に設定します。
- OSDが5~10の場合:
PG_NUMを512に設定します。
- OSDが10~50の場合:
PG_NUMを1024に設定します。
OSDの数が増えるにつれて、PG_NUMの適切な値を選択することがより重要になってきます。PG_NUMは、OSDに障害が発生した場合のクラスタの動作とデータの耐久性に強く影響します。
17.4.2.1 OSDが50を超える場合の配置グループの計算 #
OSDが50未満の場合は、17.4.2項 「PG_NUMの値の決定」で説明されている事前選択値を使用してください。OSDが50を超える場合は、リソース使用量、データ耐久性、および分散のバランスが取れるよう、OSDあたり約50~100の配置グループを推奨します。単一プールのオブジェクトの場合、次の式を使用してベースラインを取得できます。
total PGs = (OSDs * 100) / POOL_SIZE
ここで、POOL_SIZEは複製プールのレプリカ数か、ceph osd erasure-code-profile get
コマンドによって返されるイレージャコーディングプールの「k」+「m」の合計です。結果は、最も近い2の累乗値まで切り上げる必要があります。CRUSHアルゴリズムが配置グループ間でオブジェクト数をバランスよく均等に配置できるよう、切り上げを推奨します。
たとえば、OSDの数が200で、プールサイズが3つのレプリカであるクラスタの場合、次のようにPGの数を見積もります。
(200 * 100) / 3 = 6667
最も近い2の累乗値は「8192」です。
複数のデータプールを使用してオブジェクトを保存する場合、プールあたりの配置グループの数と、OSDあたりの配置グループの数のバランスを取るようにする必要があります。システムリソースの過剰な使用やピアリングプロセスの大幅な低速化を招くことなく、OSDごとの違いが適度に小さくなるような妥当な配置グループ合計数を算出する必要があります。
たとえば、10個のプールで構成されるクラスタがあり、各プールについて10個のOSDに512個の配置グループが存在する場合、合計5,120個の配置グループが10個のOSDに分散されます。つまり、OSDあたり512個の配置グループになります。このようなセットアップでは、リソースを使用し過ぎることはありません。ただし、それぞれに512個の配置グループが含まれるプールを1,000個作成した場合、OSDはそれぞれ約50,000個の配置グループを処理することになり、ピアリングに必要なリソースと時間が大幅に増えます。
17.4.3 配置グループ数の設定 #
Ceph Nautilus (v14.x)以降はCeph Managerのpg_autoscaler
モジュールを使用することで、必要に応じて配置グループを自動拡張できます。この機能を有効にしたい場合は、Section 8.1.1.1, “Default PG and PGP counts”を参照してください。
従来通りプールの配置グループ数を手動で指定する必要がある場合は、プールの作成時に指定する必要があります(18.1項 「プールの作成」を参照してください)。プールに配置グループを設定した後であれば、次のコマンドを実行して配置グループ数を増やすことができます。
#
ceph osd pool set POOL_NAME pg_num PG_NUM
配置グループの数を増やした後、クラスタの再バランスを行う前に、配置対象の配置グループの数(PGP_NUM
)を増やす必要もあります。PGP_NUM
は、配置の際にCRUSHアルゴリズムによって考慮される配置グループの数です。PG_NUM
を増やすと配置グループが分割されますが、データはPGP_NUM
を増やすまで新しい配置グループに移行されません。PGP_NUM
はPG_NUM
と等しくなければなりません。配置対象の配置グループの数を増やすには、次のコマンドを実行します。
#
ceph osd pool set POOL_NAME pgp_num PGP_NUM
17.4.4 配置グループ数の確認 #
プールの配置グループ数を確認するには、次のget
コマンドを実行します。
#
ceph osd pool get POOL_NAME pg_num
17.4.5 クラスタの配置グループの統計情報の確認 #
クラスタの配置グループの統計情報を確認するには、次のコマンドを実行します。
#
ceph pg dump [--format FORMAT]
有効な形式は「plain」(デフォルト)と「json」です。
17.4.6 スタックしている配置グループの統計情報の確認 #
指定した状態でスタックしているすべての配置グループの統計情報を確認するには、次のコマンドを実行します。
#
ceph pg dump_stuck STATE \
[--format FORMAT] [--threshold THRESHOLD]
STATEは、「inactive」(PGは最新のデータが含まれるOSDが起動するのを待機しているため、読み込みまたは書き込みを処理できない)、「unclean」(必要な回数複製されていないオブジェクトがPGに含まれている)、「stale」(PGは不明な状態で、それらのPGをホストしているOSDがmon_osd_report_timeout
オプションで指定された時間間隔でモニタクラスタにレポートしていない)、「undersized」、または「degraded」のいずれかです。
有効な形式は「plain」(デフォルト)と「json」です。
このしきい値は、配置グループがスタックしてから、返される統計情報にそれを含めるまでの最小秒数を定義します(デフォルトでは300秒)。
17.4.7 配置グループマップの検索 #
特定の配置グループの配置グループマップを検索するには、次のコマンドを実行します。
#
ceph pg map PG_ID
Cephは、配置グループマップ、配置グループ、およびOSDステータスを返します。
#
ceph pg map 1.6c
osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]
17.4.8 配置グループの統計情報の取得 #
特定の配置グループの統計情報を取得するには、次のコマンドを実行します。
#
ceph pg PG_ID query
17.4.9 配置グループのスクラブ #
配置グループをスクラブ(17.6項 「配置グループのスクラブ」)するには、次のコマンドを実行します。
#
ceph pg scrub PG_ID
Cephは、プライマリノードとレプリカノードを確認し、配置グループ内にあるすべてのオブジェクトのカタログを生成し、それらを比較して、欠落しているオブジェクトや一致しないオブジェクトがないかと、コンテンツに整合性があるかどうかを確認します。レプリカがすべて一致していれば、最後にセマンティックを一括処理して、スナップショットに関連するすべてのオブジェクトメタデータに整合性があることを確認します。エラーはログでレポートされます。
17.4.10 配置グループのバックフィルと回復の優先度の設定 #
複数の配置グループで回復やバックフィルが必要になった場合に、一部のグループに他のグループよりも重要なデータが格納されている状況が発生することがあります。たとえば、一部のPGには稼働中のマシンで使用されているイメージのデータが格納されていて、他のPGは非アクティブなマシンや関連性の低いデータで使用されている場合があります。このような場合、これらのグループの回復の優先度を設定して、該当するグループに保存されているデータのパフォーマンスと可用性を先に復元できます。バックフィルまたは回復中に特定の配置グループに優先のマークを付けるには、次のコマンドを実行します。
#
ceph pg force-recovery PG_ID1 [PG_ID2 ... ]#
ceph pg force-backfill PG_ID1 [PG_ID2 ... ]
これにより、Cephは、他の配置グループより先に、まず指定した配置グループに対して回復またはバックフィルを実行します。これは、現在進行中のバックフィルや回復を中断するのではなく、指定したPGをできるだけ早く処理するものです。考えが変わった場合、または間違ったグループに優先度を設定した場合は、次のコマンドを使用して、優先度の設定をキャンセルします。
#
ceph pg cancel-force-recovery PG_ID1 [PG_ID2 ... ]#
ceph pg cancel-force-backfill PG_ID1 [PG_ID2 ... ]
cancel-*
コマンドを使用すると、PGから「force」フラグが削除され、PGはデフォルトの順序で処理されるようになります。このコマンドも、現在処理中の配置グループには影響せず、まだキューに入っている配置グループにのみ影響します。グループの回復またはバックフィルが完了すると、「force」フラグは自動的にクリアされます。
17.4.11 失われたオブジェクトを元に戻す #
クラスタで1つ以上のオブジェクトが失われ、失われたデータの検索を中止する場合は、見つからないオブジェクトに「喪失」のマークを付ける必要があります。
可能性がある場所すべてに対してクエリを実行してもまだオブジェクトが失われた状態である場合、失なわれたオブジェクトを放棄しなければならないことがあります。これは、書き込みそのものが回復される前に実行された書き込みをクラスタが認識できるような複数の障害がまれな組み合わせで起きた場合に発生する可能性があります。
現在サポートされている唯一のオプションは「revert」で、以前のバージョンのオブジェクトにロールバックするか、新しいオブジェクトの場合はその情報を完全に消去します。「見つからない」オブジェクトに「喪失」のマークを付けるには、次のコマンドを実行します。
cephuser@adm >
ceph pg PG_ID mark_unfound_lost revert|delete
17.4.12 配置グループの自動拡張の有効化 #
配置グループ(PG)とは、Cephのデータ分散方法を内部で実装している詳細部分です。配置グループの自動拡張を有効化することで、クラスタの使用方法に応じてクラスタが配置グループの作成や自動調整を行えるようにします。
システム上の各プールにはpg_autoscale_mode
というプロパティがあり、off
、on
、warn
に設定することが可能です。
自動拡張はプールごとに設定します。また、次の3つのモードで動作します。
- off
このプールの自動拡張を無効化します。管理者の判断で、各プールに適切な数の配置グループを選択してください。
- on
対象プールで配置グループ数の自動調整を有効化します。
- warn
配置グループ数を調整する必要がある場合に、ヘルスアラートを発します。
既存のプールに自動拡張モードを設定するには、次のコマンドを実行します。
cephuser@adm >
ceph osd pool set POOL_NAME pg_autoscale_mode mode
デフォルトのpg_autoscale_mode
を設定することもできます。この設定は今後作成されるすべてのプールに適用されます。コマンドは次の通りです。
cephuser@adm >
ceph config set global osd_pool_default_pg_autoscale_mode MODE
次のコマンドを実行することで、各プール、その相対的な使用率、推奨される配置グループ数の変更を確認できます。
cephuser@adm >
ceph osd pool autoscale-status
17.5 CRUSHマップの操作 #
このセクションでは、CRUSHマップの編集やパラメータの変更、OSDの追加/移動/削除など、CRUSHマップの基本的な操作方法を紹介します。
17.5.1 CRUSHマップの編集 #
既存のCRUSHマップを編集するには、次の手順に従います。
CRUSHマップを取得します。クラスタのCRUSHマップを取得するには、次のコマンドを実行します。
cephuser@adm >
ceph osd getcrushmap -o compiled-crushmap-filenameCephにより、指定したファイル名に、コンパイル済みのCRUSHマップが出力(
-o
)されます。CRUSHマップはコンパイル済み形式なので、編集する前に逆コンパイルする必要があります。CRUSHマップを逆コンパイルします。CRUSHマップを逆コンパイルするには、次のコマンドを実行します。
cephuser@adm >
crushtool -d compiled-crushmap-filename \ -o decompiled-crushmap-filenameCephにより、コンパイル済みのCRUSHマップが逆コンパイル(
-d
)されて、指定したファイル名に出力(-o
)されます。デバイス、バケット、およびルールのパラメータを少なくとも1つ編集します。
CRUSHマップをコンパイルします。CRUSHマップをコンパイルするには、次のコマンドを実行します。
cephuser@adm >
crushtool -c decompiled-crush-map-filename \ -o compiled-crush-map-filenameCephにより、指定したファイル名に、コンパイル済みのCRUSHマップが保存されます。
CRUSHマップを設定します。クラスタのCRUSHマップを設定するには、次のコマンドを実行します。
cephuser@adm >
ceph osd setcrushmap -i compiled-crushmap-filenameCephにより、指定したファイル名のコンパイル済みCRUSHマップがクラスタのCRUSHマップとして入力されます。
エクスポートおよび変更したCRUSHマップファイルには、gitやsvnなどのバージョン管理システムを使用します。これにより、ロールバックを簡単に行うことができます。
調整した新しいCRUSHマップは、crushtool --test
コマンドを使用してテストし、新しいCRUSHマップを適用する前の状態と比較します。次のコマンドスイッチが役立つ場合があります。--show-statistics
、--show-mappings
、--show-bad-mappings
、--show-utilization
、--show-utilization-all
、--show-choose-tries
17.5.2 OSDの追加または移動 #
実行中のクラスタのCRUSHマップでOSDを追加または移動するには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush set id_or_name weight root=pool-name
bucket-type=bucket-name ...
- id
整数。OSDの数値ID。このオプションは必須です。
- name
文字列。OSDの完全な名前。このオプションは必須です。
- weight
倍精度。OSDのCRUSHの重み。このオプションは必須です。
- root
キー/値のペア。CRUSH階層には、デフォルトでそのルートとしてプールが含まれます。このオプションは必須です。
- bucket-type
キー/値のペア。CRUSH階層におけるOSDの場所を指定できます。
次の例は、osd.0
を階層に追加するか、前の場所からそのOSDを移動します。
cephuser@adm >
ceph osd crush set osd.0 1.0 root=data datacenter=dc1 room=room1 \
row=foo rack=bar host=foo-bar-1
17.5.3 ceph osd reweight
とceph osd crush reweight
の違い #
Ceph OSDの「重み」を変更する、類似するコマンドが2つあります。これらを使用するコンテキストは異なるため、混乱を招く可能性があります。
17.5.3.1 ceph osd reweight
#
使用方法:
cephuser@adm >
ceph osd reweight OSD_NAME NEW_WEIGHT
ceph osd reweight
はCeph OSDに上書きの重みを設定します。この値は0~1の範囲です。それ以外の値に設定すると、CRUSHは、通常であればこのドライブ上に存続するデータを強制的に再配置します。OSD上のバケットに割り当てられた重みは変更「しません」。これは、CRUSHによる通常の分散が適切に機能しない場合の修正手段です。たとえば、OSDの1つが90%で、その他が40%の場合、この重みを減らして補正を試してみることができます。
ceph osd reweight
は永続的な設定ではないことに注意してください。あるOSDにマークを付けるとその重みは0に設定され、もう一度マークを付けるとその重みは1に変更されます。
17.5.3.2 ceph osd crush reweight
#
使用方法:
cephuser@adm >
ceph osd crush reweight OSD_NAME NEW_WEIGHT
ceph osd crush reweight
は、OSDの「CRUSH」の重みを設定します。この重みは任意の値(一般的にはディスクのTB単位のサイズ)で、システムがOSDに割り当てようとするデータの量を制御します。
17.5.4 OSDの削除 #
実行中のクラスタのCRUSHマップからOSDを削除するには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush remove OSD_NAME
17.5.5 バケットの追加 #
実行中のクラスタのCRUSHマップにバケットを追加するには、ceph osd crush add-bucket
コマンドを実行します。
cephuser@adm >
ceph osd crush add-bucket BUCKET_NAME BUCKET_TYPE
17.5.6 バケットの移動 #
CRUSHマップ階層の別の場所または位置へバケットを移動するには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush move BUCKET_NAME BUCKET_TYPE=BUCKET_NAME [...]
以下に例を示します。
cephuser@adm >
ceph osd crush move bucket1 datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1
17.5.7 バケットの削除 #
CRUSHマップ階層からバケットを削除するには、次のコマンドを実行します。
cephuser@adm >
ceph osd crush remove BUCKET_NAME
CRUSH階層からバケットを削除する前に、バケットを空にする必要があります。
17.6 配置グループのスクラブ #
オブジェクトの複数のコピーを作成するほかに、Cephは、配置グループを「スクラブ」することによってデータの整合性を保証します(配置グループの詳細については、1.3.2項 「配置グループ」を参照)。Cephのスクラブは、Object Storage層に対してfsck
を実行することに似ています。各配置グループについて、Cephは、すべてのオブジェクトのカタログを生成し、各プライマリオブジェクトとそのレプリカを比較して、オブジェクトの欠落や不一致がないことを確認します。日次の軽量スクラブではオブジェクトのサイズと属性を確認するのに対し、週次の詳細スクラブではデータを読み込み、チェックサムを使用してデータの整合性を保証します。
スクラブはデータの整合性を維持するために重要ですが、パフォーマンスを低下させる可能性があります。次の設定を調整して、スクラブ操作を増減できます。
osd max scrubs
Ceph OSDの同時スクラブ操作の最大数。デフォルトは1です。
osd scrub begin hour
、osd scrub end hour
スクラブを実行可能な時間枠を定義する時間(0~24)。デフォルトでは、0から始まり24に終了します。
重要配置グループのスクラブ間隔が
osd scrub max interval
の設定を超えている場合、スクラブは、定義した時間枠とは関係なく実行されます。osd scrub during recovery
回復時のスクラブを許可します。「false」に設定すると、アクティブな回復がある間は、新しいスクラブのスケジューリングが無効になります。すでに実行中のスクラブは続行されます。このオプションは、高負荷のクラスタの負荷を下げる場合に役立ちます。デフォルトは「true」です。
osd scrub thread timeout
スクラブスレッドがタイムアウトするまでの最大時間(秒単位)。デフォルトは60です。
osd scrub finalize thread timeout
スクラブ最終処理スレッドがタイムアウトするまでの最大時間(秒単位)。デフォルトは60*10です。
osd scrub load threshold
正規化された最大負荷。システム負荷(
getloadavg()
/online cpus
の数の比率で定義)がこの数字を超えた場合、Cephはスクラブを実行しません。デフォルトは0.5です。osd scrub min interval
Cephクラスタの負荷が低い場合にCeph OSDをスクラブする最小間隔(秒単位)。デフォルトは60*60*24 (1日1回)です。
osd scrub max interval
クラスタの負荷に関係なくCeph OSDをスクラブする最大間隔(秒単位)。デフォルトは7*60*60*24 (週1回)です。
osd scrub chunk min
1回の操作でスクラブするObject Storeチャンクの最大数。スクラブ中、Cephは1つのチャンクへの書き込みをブロックします。デフォルトは5です。
osd scrub chunk max
1回の操作でスクラブするObject Storeチャンクの最大数。デフォルトは25です。
osd scrub sleep
チャンクの次のグループをスクラブするまでのスリープ時間。この値を増やすとスクラブ操作全体の速度が低下しますが、クライアントの操作への影響は少なくなります。デフォルトは0です。
osd deep scrub interval
「詳細」スクラブ(すべてのデータを完全に読み込み)の間隔。
osd scrub load threshold
オプションはこの設定に影響しません。デフォルトは60*60*24*7 (週1回)です。osd scrub interval randomize ratio
配置グループに対して次のスクラブジョブをスケジューリングする際に、
osd scrub min interval
の値にランダムな遅延を追加します。この遅延は、osd scrub min interval
*osd scrub interval randomized ratio
の結果よりも小さいランダムな値です。したがって、デフォルト設定では、許可された時間枠である[1, 1.5] *osd scrub min interval
の中で実質的にランダムにスクラブが分散されます。デフォルトは0.5です。osd deep scrub stride
詳細スクラブ実行時の読み込みサイズ。デフォルトは524288 (512KB)です。