目次にジャンプページナビゲーションにジャンプ: 前のページ[アクセスキーp]/次のページ[アクセスキーn]
documentation.suse.com / SUSE Enterprise Storage 7マニュアル / 運用と管理ガイド / クラスタへのデータ保存 / 保存データの管理
適用項目 SUSE Enterprise Storage 7

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つあります。

  • OSDデバイスは、ceph-osdデーモンに対応するオブジェクトストレージデバイスで構成されます。

  • バケットは、ストレージの場所の階層的な集約構造(列、ラック、ホストなど)と、それらに割り当てられている重みで構成されます。

  • ルールセットは、バケットの選択方法で構成されます。

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.3class 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ルールを簡単に割り当てたりすることができます。

複数のデバイスクラスが混在するOSD
図 17.1: 複数のデバイスクラスが混在するOSD

ただし、データを特定のデバイスクラスにのみ配置するように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,3
cephuser@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=host
cephuser@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 original
cephuser@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(osd.1osd.2、など)。

1

ホスト

1つ以上のOSDを含むホストの名前。

2

シャーシ

ラック内のどのシャーシにホストが存在するかを識別するID。

3

ラック

コンピュータラック。デフォルトはunknownrackです。

4

一連のラックの列。

5

pdu

「Power Distribution Unit」(配電ユニット)の略語。

6

ポッド

「Point of Delivery」の略語。ここでは、ひとかたまりのPDUやラック列を指します。

7

ルーム

ラック列が設置されている部屋。

8

データセンター

1つ以上のルームを含む、物理的なデータセンター。

9

地域

世界の地理的地域(たとえば、NAM、LAM、EMEA、APACなど)。

10

root

OSDバケットツリーのルートノード(通常は、defaultに設定されます)。

ヒント
ヒント

既存のタイプを変更して独自のバケットタイプを作成できます。

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

targetchooseまたはchooseleafのいずれかにできます。chooseに設定すると、大量のバケットが選択されます。chooseleafは、バケットセット内の各バケットのサブツリーからOSD (リーフノード)を直接選択します。

modefirstnまたはindepのいずれかにできます。17.3.2項 「firstnindepを参照してください。

特定のタイプのバケットの数を指定します。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を使用してツリー全体で反復処理を行う例を示します。次のルール定義では、オレンジ色の矢印と番号はexample1aexample1bに対応し、青色はexample2に対応します。

ツリーの例
図 17.2: ツリーの例
# 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 firstnindep

CRUSHルールは、障害ノードまたはOSDの置換を定義します(17.3項 「ルールセット」を参照してください)。キーワードstepには、パラメータとしてfirstnまたはindepが必要です。図17.3「ノードの置換方法」に例を示します。

firstnは、アクティブノードのリストの最後に置換ノードを追加します。障害ノードの場合、以降の正常なノードが左側に移動されて、障害ノードの隙間を埋めます。これは、「複製プール」に対するデフォルトかつ適切な方法です。2つ目のノードにはすでにすべてのデータがあるため、プライマリノードの権限をただちに引き継ぐことができるからです。

indepは、各アクティブノードに対して修復済みの置換ノードを選択します。障害ノードを置換する際に、残りのノードの順序は変更されません。これは「イレージャコーディングプール」にとって適切です。イレージャコーディングプールでは、ノードに保存されるデータは、ノード選択時の位置によって異なります。ノードの順序が変更されると、影響を受けるノードのすべてのデータを再配置しなければなりません。

ノードの置換方法
図 17.3: ノードの置換方法

17.4 配置グループ

Cephは、オブジェクトをPG (配置グループ)にマップします。配置グループは、オブジェクトをグループとしてOSDに配置する、論理オブジェクトプールのシャードまたはフラグメントです。配置グループにより、CephがOSDにデータを保存する際のオブジェクトごとのメタデータの量が削減されます。配置グループの数が多いほど(たとえば、OSDあたり100など)、バランスが向上します。

17.4.1 配置グループの使用

PG (配置グループ)は複数のオブジェクトを1つのプール内に集約します。この主な理由は、オブジェクトごとにオブジェクトの配置とメタデータを追跡すると、計算コストが高くなるためです。たとえば、何百万ものオブジェクトが存在するシステムでは、その各オブジェクトの配置を直接追跡することはできません。

プール内の配置グループ
図 17.4: プール内の配置グループ

Cephクライアントは、オブジェクトが属する配置グループを計算します。このために、オブジェクトIDをハッシュし、定義されたプール内のPGの数と、プールのIDに基づいて操作を適用します。

配置グループ内のオブジェクトのコンテンツは、一連のOSDに保存されます。たとえば、サイズが2の複製プールでは、各配置グループは次のように2つのOSDにオブジェクトを保存します。

配置グループとOSD
図 17.5: 配置グループと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モジュールを使用することで、必要に応じて配置グループを自動拡張できます。この機能を有効にしたい場合は、6.1.1.1項 「Default PG and PGP counts」を参照してください。

新しいプールを作成するときに、PG_NUMの値を従来通り手動で選択することも可能です。

root # 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モジュールを使用することで、必要に応じて配置グループを自動拡張できます。この機能を有効にしたい場合は、6.1.1.1項 「Default PG and PGP counts」を参照してください。

従来通りプールの配置グループ数を手動で指定する必要がある場合は、プールの作成時に指定する必要があります(18.1項 「プールの作成」を参照してください)。プールに配置グループを設定した後であれば、次のコマンドを実行して配置グループ数を増やすことができます。

root # ceph osd pool set POOL_NAME pg_num PG_NUM

配置グループの数を増やした後、クラスタの再バランスを行う前に、配置対象の配置グループの数(PGP_NUM)を増やす必要もあります。PGP_NUMは、配置の際にCRUSHアルゴリズムによって考慮される配置グループの数です。PG_NUMを増やすと配置グループが分割されますが、データはPGP_NUMを増やすまで新しい配置グループに移行されません。PGP_NUMPG_NUMと等しくなければなりません。配置対象の配置グループの数を増やすには、次のコマンドを実行します。

root # ceph osd pool set POOL_NAME pgp_num PGP_NUM

17.4.4 配置グループ数の確認

プールの配置グループ数を確認するには、次のgetコマンドを実行します。

root # ceph osd pool get POOL_NAME pg_num

17.4.5 クラスタの配置グループの統計情報の確認

クラスタの配置グループの統計情報を確認するには、次のコマンドを実行します。

root # ceph pg dump [--format FORMAT]

有効な形式は「plain」(デフォルト)と「json」です。

17.4.6 スタックしている配置グループの統計情報の確認

指定した状態でスタックしているすべての配置グループの統計情報を確認するには、次のコマンドを実行します。

root # 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 配置グループマップの検索

特定の配置グループの配置グループマップを検索するには、次のコマンドを実行します。

root # ceph pg map PG_ID

Cephは、配置グループマップ、配置グループ、およびOSDステータスを返します。

root # ceph pg map 1.6c
osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]

17.4.8 配置グループの統計情報の取得

特定の配置グループの統計情報を取得するには、次のコマンドを実行します。

root # ceph pg PG_ID query

17.4.9 配置グループのスクラブ

配置グループをスクラブ(17.6項 「配置グループのスクラブ」)するには、次のコマンドを実行します。

root # ceph pg scrub PG_ID

Cephは、プライマリノードとレプリカノードを確認し、配置グループ内にあるすべてのオブジェクトのカタログを生成し、それらを比較して、欠落しているオブジェクトや一致しないオブジェクトがないかと、コンテンツに整合性があるかどうかを確認します。レプリカがすべて一致していれば、最後にセマンティックを一括処理して、スナップショットに関連するすべてのオブジェクトメタデータに整合性があることを確認します。エラーはログでレポートされます。

17.4.10 配置グループのバックフィルと回復の優先度の設定

複数の配置グループで回復やバックフィルが必要になった場合に、一部のグループに他のグループよりも重要なデータが格納されている状況が発生することがあります。たとえば、一部のPGには稼働中のマシンで使用されているイメージのデータが格納されていて、他のPGは非アクティブなマシンや関連性の低いデータで使用されている場合があります。このような場合、これらのグループの回復の優先度を設定して、該当するグループに保存されているデータのパフォーマンスと可用性を先に復元できます。バックフィルまたは回復中に特定の配置グループに優先のマークを付けるには、次のコマンドを実行します。

root # ceph pg force-recovery PG_ID1 [PG_ID2 ... ]
root # ceph pg force-backfill PG_ID1 [PG_ID2 ... ]

これにより、Cephは、他の配置グループより先に、まず指定した配置グループに対して回復またはバックフィルを実行します。これは、現在進行中のバックフィルや回復を中断するのではなく、指定したPGをできるだけ早く処理するものです。考えが変わった場合、または間違ったグループに優先度を設定した場合は、次のコマンドを使用して、優先度の設定をキャンセルします。

root # ceph pg cancel-force-recovery PG_ID1 [PG_ID2 ... ]
root # 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というプロパティがあり、offonwarnに設定することが可能です。

自動拡張はプールごとに設定します。また、次の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マップを編集するには、次の手順に従います。

  1. CRUSHマップを取得します。クラスタのCRUSHマップを取得するには、次のコマンドを実行します。

    cephuser@adm > ceph osd getcrushmap -o compiled-crushmap-filename

    Cephにより、指定したファイル名に、コンパイル済みのCRUSHマップが出力(-o)されます。CRUSHマップはコンパイル済み形式なので、編集する前に逆コンパイルする必要があります。

  2. CRUSHマップを逆コンパイルします。CRUSHマップを逆コンパイルするには、次のコマンドを実行します。

    cephuser@adm > crushtool -d compiled-crushmap-filename \
     -o decompiled-crushmap-filename

    Cephにより、コンパイル済みのCRUSHマップが逆コンパイル(-d)されて、指定したファイル名に出力(-o)されます。

  3. デバイス、バケット、およびルールのパラメータを少なくとも1つ編集します。

  4. CRUSHマップをコンパイルします。CRUSHマップをコンパイルするには、次のコマンドを実行します。

    cephuser@adm > crushtool -c decompiled-crush-map-filename \
     -o compiled-crush-map-filename

    Cephにより、指定したファイル名に、コンパイル済みのCRUSHマップが保存されます。

  5. CRUSHマップを設定します。クラスタのCRUSHマップを設定するには、次のコマンドを実行します。

    cephuser@adm > ceph osd setcrushmap -i compiled-crushmap-filename

    Cephにより、指定したファイル名のコンパイル済みCRUSHマップがクラスタのCRUSHマップとして入力されます。

ヒント
ヒント: バージョン管理システムの使用

エクスポートおよび変更したCRUSHマップファイルには、gitやsvnなどのバージョン管理システムを使用します。これにより、ロールバックを簡単に行うことができます。

ヒント
ヒント: 新しいCRUSHマップのテスト

調整した新しい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 reweightceph 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%の場合、この重みを減らして補正を試してみることができます。

注記
注記: OSDの重みは一時的である

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 hourosd 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)です。