こんにちは、キクです。
本記事は、僕が自己学習で学んだことをブログでアウトプットするシリーズになります。
今回は『Cephにおけるデータの分散配置』について書いていこうと思います。
本記事の内容
それでは、よろしくお願いします。
データの分散配置に関わるあれこれ
Crush Mapにおけるバケットタイプ
次のようなバケットタイプがある
ほとんどのクラスタではこれらのタイプのうち少数のみを使用する
Crush rule
階層内のデバイス間でデータをどのように分散するかを管理するポリシーを定義
以下はデフォルトで存在するルール
root@ceph01:~# ceph osd crush rule dump
[
{
"rule_id": 0,
"rule_name": "replicated_rule",
"type": 1,
"steps": [
{
"op": "take",
"item": -1,
"item_name": "default"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
}
]
「”item_name”: default」はデフォルトで存在しているバケット「root:default」を指している
ルールの作成について
公式ドキュメントにある以下のコマンドのように、ルールの作成時には「failure-domain」として「host」や「chassis」などの指定をする
# ceph osd crush rule create-replicated <rule-name> <root> <failure-domain> <class>
これによりデータを分散する単位を指定しているという認識
また「class」はデバイスクラスを表し、ここでは「hdd」や「ssd」「nvme」などを指定する
これにより、このルールを割り当てたプールに参加するデバイスタイプを指定できるものと思われる
参考:CREATING A RULE FOR A REPLICATED POOL
デバイスクラス
各デバイスにオプションとして割り当てることができる情報
デフォルトではOSD起動時にサポートされるデバイスタイプに応じて「hdd / ssd / nvme」のいずれかが自動的に割り当てられる
下記の場合は各OSDは「hdd」として認識されていることになる
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.03918 root default
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
なお、デバイスタイプは手動で変更することも可能
$ ceph osd crush set-device-class クラス名 osd.xx
実戦練習
バケットの作成
root@ceph01:~# ceph osd crush add-bucket test-chassis1 chassis
added bucket test-chassis1 type chassis to crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
新たに追加されたバケットはまずバケットタイプ「root(名前:default)」の直下に配置される認識だったが、実際に作ってみたらrootと横並びで作成されることが分かった
タイプ「zone」のバケット「z-hdd」を作成
root@ceph01:~# ceph osd crush add-bucket z-hdd zone
added bucket z-hdd type zone to crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-12 0 zone z-hdd
-11 0 chassis test-chassis1
-1 0.03918 root default
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
バケットおよびOSDの移動
バケット「z-hdd」を「root:default」直下に移動
root@ceph01:~# ceph osd crush move z-hdd root=default
moved item id -12 name 'z-hdd' to location {root=default} in crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
デバイスクラス「hdd」のOSDが稼働中の2ホストを「z-hdd」配下に移動
root@ceph01:~# ceph osd crush move ceph01 zone=z-hdd
moved item id -3 name 'ceph01' to location {zone=hdd} in crush map
root@ceph01:~# ceph osd crush move ceph02 zone=z-hdd
moved item id -5 name 'ceph02' to location {zone=hdd} in crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
デバイスクラスの変更
デバイスクラスを変更してみる
root@ceph01:~# ceph osd crush set-device-class ssd osd.3
Error EBUSY: osd.3 has already bound to class 'hdd', can not reset class to 'ssd'; use 'ceph osd crush rm-device-class <id>' to remove old class first
roo
-> 失敗
root@ceph01:~# ceph osd crush rm-device-class 3
done removing class of osd(s): 3
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 0.00980 osd.3 up 1.00000 1.00000
root@ceph01:~# ceph osd crush set-device-class ssd osd.3
set osd(s) 3 to class 'ssd'
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 ssd 0.00980 osd.3 up 1.00000 1.00000
SSD用ゾーン(バケット)の作成およびOSDの移動
タイプ「zone」のバケット「z-ssd」を作成して、デバイスタイプ「ssd」のOSDが稼働しているホストを参加させる
root@ceph01:~# ceph osd crush add-bucket z-ssd zone
added bucket z-ssd type zone to crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-22 0 zone z-ssd
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 ssd 0.00980 osd.3 up 1.00000 1.00000
root@ceph01:~# ceph osd crush move z-ssd root=default
moved item id -22 name 'z-ssd' to location {root=default} in crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 ssd 0.00980 osd.3 up 1.00000 1.00000
-22 0 zone z-ssd
root@ceph01:~# ceph osd crush move ceph04 zone=z-ssd
moved item id -9 name 'ceph04' to location {zone=z-ssd} in crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-11 0 chassis test-chassis1
-1 0.03918 root default
-12 0.01959 zone z-hdd
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-22 0.00980 zone z-ssd
-9 0.00980 host ceph04
3 ssd 0.00980 osd.3 up 1.00000 1.00000
構成整理
chassisバケット#1の整理
root@ceph01:~# ceph osd crush move test-chassis1 zone=z-hdd
moved item id -11 name 'test-chassis1' to location {zone=z-hdd} in crush map
root@ceph01:~# ceph osd crush move ceph01 chassis=test-chassis1
moved item id -3 name 'ceph01' to location {chassis=test-chassis1} in crush map
root@ceph01:~# ceph osd crush move ceph02 chassis=test-chassis1
moved item id -5 name 'ceph02' to location {chassis=test-chassis1} in crush map
chassisバケット#2の追加および整理
root@ceph01:~# ceph osd crush add-bucket test-chassis2 chassis
added bucket test-chassis2 type chassis to crush map
root@ceph01:~# ceph osd crush move test-chassis2 zone=z-hdd
moved item id -15 name 'test-chassis2' to location {zone=z-hdd} in crush map
root@ceph01:~# ceph osd crush rm-device-class 3
done removing class of osd(s): 3
root@ceph01:~# ceph osd crush set-device-class hdd osd.3
set osd(s) 3 to class 'hdd'
root@ceph01:~# ceph osd crush move ceph03 chassis=test-chassis2
moved item id -7 name 'ceph03' to location {chassis=test-chassis2} in crush map
root@ceph01:~# ceph osd crush move ceph04 chassis=test-chassis2
moved item id -9 name 'ceph04' to location {chassis=test-chassis2} in crush map
状況確認
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.03918 root default
-12 0.03918 zone z-hdd
-11 0.01959 chassis test-chassis1
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-15 0.01959 chassis test-chassis2
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
-22 0 zone z-ssd
Crush rule設定
chassisレベルでの分散ルールの作成/適用
root@ceph01:~# ceph osd crush rule create-simple test-rule-chassis z-hdd chassis
root@ceph01:~# ceph osd crush rule dump test-rule-chassis
{
"rule_id": 1,
"rule_name": "test-rule-chassis",
"type": 1,
"steps": [
{
"op": "take",
"item": -12,
"item_name": "z-hdd"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "chassis"
},
{
"op": "emit"
}
]
}
root@ceph01:~# ceph osd pool set rdb crush_rule test-rule-chassis
set pool 2 crush_rule to test-rule-chassis
root@ceph01:~# ceph -s
cluster:
id: 1950c5ce-2528-11ef-af77-c9b795315e84
health: HEALTH_OK
services:
mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 3m)
mgr: ceph02.yqwrrm(active, since 4h), standbys: ceph01.ysiryi
osd: 4 osds: 4 up (since 4h), 4 in (since 12d); 32 remapped pgs
data:
pools: 2 pools, 33 pgs
objects: 272 objects, 1.0 GiB
usage: 4.2 GiB used, 36 GiB / 40 GiB avail
pgs: 270/816 objects misplaced (33.088%)
32 active+clean+remapped
1 active+clean
データ移動は開始されたが、「33.088%」から一向に進まない
-> 現在chassisが2つしかないため「3冗長ができない」というのが原因の可能性あり
試しに新しいシャーシ「test-chassis3」を追加して、1ホスト(ceph04)をそこに追加してみる
root@ceph01:~# ceph osd crush add-bucket test-chassis3 chassis
added bucket test-chassis3 type chassis to crush map
root@ceph01:~# ceph osd crush move test-chassis3 zone=z-hdd
moved item id -16 name 'test-chassis3' to location {zone=z-hdd} in crush map
root@ceph01:~# ceph osd crush move ceph04 chassis=test-chassis3
moved item id -9 name 'ceph04' to location {chassis=test-chassis3} in crush map
root@ceph01:~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.03918 root default
-12 0.03918 zone z-hdd
-11 0.01959 chassis test-chassis1
-3 0.00980 host ceph01
0 hdd 0.00980 osd.0 up 1.00000 1.00000
-5 0.00980 host ceph02
1 hdd 0.00980 osd.1 up 1.00000 1.00000
-15 0.00980 chassis test-chassis2
-7 0.00980 host ceph03
2 hdd 0.00980 osd.2 up 1.00000 1.00000
-16 0.00980 chassis test-chassis3
-9 0.00980 host ceph04
3 hdd 0.00980 osd.3 up 1.00000 1.00000
-22 0 zone z-ssd
root@ceph01:~# ceph -s
cluster:
id: 1950c5ce-2528-11ef-af77-c9b795315e84
health: HEALTH_WARN
Degraded data redundancy: 26/816 objects degraded (3.186%), 3 pgs degraded
services:
mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 6m)
mgr: ceph02.yqwrrm(active, since 4h), standbys: ceph01.ysiryi
osd: 4 osds: 4 up (since 4h), 4 in (since 12d); 2 remapped pgs
data:
pools: 2 pools, 33 pgs
objects: 272 objects, 1.0 GiB
usage: 4.2 GiB used, 36 GiB / 40 GiB avail
pgs: 26/816 objects degraded (3.186%)
214/816 objects misplaced (26.225%)
26 active+clean+remapped
4 active+clean
3 active+recovery_wait+degraded
-> 動き出した!
root@ceph01:~# ceph -s
cluster:
id: 1950c5ce-2528-11ef-af77-c9b795315e84
health: HEALTH_OK
services:
mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 7m)
mgr: ceph02.yqwrrm(active, since 4h), standbys: ceph01.ysiryi
osd: 4 osds: 4 up (since 4h), 4 in (since 12d)
data:
pools: 2 pools, 33 pgs
objects: 272 objects, 1.0 GiB
usage: 4.2 GiB used, 36 GiB / 40 GiB avail
pgs: 33 active+clean
-> 無事完了
関連調査メモ
「create-replicated」と「create-simple」
Crush rule作成時に利用するサブコマンドだが、前者はより詳細なポリシーを組みたい場合に使う模様
後者は「基本的にはデフォルトの設定で十分」という場合に簡易的にポリシーが組めるもので、デバイスクラスの指定ができないなどの制限もある
クラス指定して作ろうとしたら以下のようなエラーになった
root@ceph01:~# ceph osd crush rule create-simple test_rule2 default host hdd
hdd not valid: hdd not in firstn|indep
Invalid command: unused arguments: ['hdd']
osd crush rule create-simple <name> <root> <type> [<mode:firstn|indep>] : create crush rule <name> to start from <ro
Error EINVAL: invalid command
「chooseleaf_firstn」と「chooseleaf_indep」の違い
ざっくり書くと以下の違い
レプリカ数の設定場所
各プール毎にレプリカ数を設定することが可能(デフォルト:3)
ただし、レプリカ数を増やせばストレージ使用量や書き込み操作のオーバーヘッドが増える可能性があるので、慎重に考えて設定すること
以下のように確認可能(size=レプリカ数)
root@ceph01:~# ceph osd pool get プール名 all
size: 3
min_size: 2
pg_num: 32
pgp_num: 32
crush_rule: test-rule-chassis
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
eio: false
bulk: false
root@ceph01:~# ceph osd pool get プール名 size
size: 3
root@ceph01:~# ceph osd pool ls detail
pool 1 '.mgr' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 21 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr
pool 2 'rdb' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 909 lfor 0/476/474 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd
プールタイプについて
replicated
指定されたレプリカ数のデータを複製することでデータを保護する
読み込み・書き込みともに高いパフォーマンスを発揮
ただし、指定したレプリカ数だけのリソースが必要なため、ストレージ効率は高くない
erasure-coded
データをブロックに分割して、冗長データ(パリティみたいなもの)を追加して保存することでデータを保護する
replicatedに比べて以下のような違いがある
erasure-codedでは「データブロック(k)」と「冗長データ(m)」にデータが分割されて、それぞれ別のOSDに保存される
例えば冗長データ(m)を「3」に設定していた場合、3個の破損までは復旧が可能
replicatedがデータ丸々を複数のOSDに分散していたのに対して、erasure-codedは1つのデータを復元可能な状態に分割して分散することから「ストレージ効率が高い」ということになる
また、erasure-codedの場合のpoolの設定値「size」については、レプリカ数ではなく「k」と「m」の合計値を表している
ちなみに「k」と「m」の値は以下のようにして確認できる
root@ceph01:~# ceph osd erasure-code-profile ls
default
test-profile
root@ceph01:~# ceph osd erasure-code-profile get test-profile
k=3
m=2
erasure-codeのpoolを作成する場合、プール作成時に上記のerasure-code-profileを「erasure プロファイル名」という形で指定することでそのプールにおける「データ」「 冗長データ」の配分を決める
上記の「default」をプロファイルとして指定した場合は「k=2, m=2」の配分でデータが分割されて分散される
各プールタイプによってプール一覧を表示した際の表示項目にも変化がある
# ceph osd pool ls ls detail
pool 1 '.mgr' replicated size 3 min_size 2 crush_rule 1 ~
pool 2 'test-pool' erasure profile test-profile size 5 min_size 4 crush_rule 2 ~
用語メモ:leafnode
leafnodeはOSDと同義っぽい
つまりcrush ruleに含まれる「chooseleaf」の「type(例:hostやchassis)」は「利用するOSDはどの単位で選定するか?」という認識で大丈夫そう
別件メモ:本件と関係ないアラートの解消対応
今回の作業内容とは関係ないが、作業時にmon#4の時刻ズレに伴うエラーが発生していた
root@ceph01:~# ceph -s
cluster:
id: 1950c5ce-2528-11ef-af77-c9b795315e84
health: HEALTH_WARN
clock skew detected on mon.ceph04
services:
mon: 4 daemons, quorum ceph01,ceph02,ceph03,ceph04 (a
mgr: ceph02.yqwrrm(active, since 3h), standbys: ceph01.ysiryi
osd: 4 osds: 4 up (since 3h), 4 in (since 12d)
data:
pools: 2 pools, 33 pgs
objects: 272 objects, 1.0 GiB
usage: 4.2 GiB used, 36 GiB / 40 GiB avail
pgs: 33 active+clean
鬱陶しかったので一度mon#4を削除してみたが、自動で再作成されてしまう状況だった
以下のコマンドでmonの自動作成を無効化した後に削除したら、再作成もされずに「HEALTH_OK」になった
root@ceph01:~# ceph orch set-unmanaged mon
root@ceph01:~# ceph orch daemon stop mon.ceph04
Scheduled to stop mon.ceph04 on host 'ceph04'
root@ceph01:~# ceph orch daemon rm mon.ceph04 --force
Removed mon.ceph04 from host 'ceph04'
root@ceph01:~# ceph -s
cluster:
id: 1950c5ce-2528-11ef-af77-c9b795315e84
health: HEALTH_OK
services:
mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 12s)
mgr: ceph02.yqwrrm(active, since 4h), standbys: ceph01.ysiryi
osd: 4 osds: 4 up (since 4h), 4 in (since 12d); 32 remapped pgs
data:
pools: 2 pools, 33 pgs
objects: 272 objects, 1.0 GiB
usage: 4.2 GiB used, 36 GiB / 40 GiB avail
pgs: 270/816 objects misplaced (33.088%)
32 active+clean+remapped
1 active+clean