一、前言:
有很多场景,你需要在指定的 OSD 设备上创建 Ceph Pool。因为Ceph集群中允许使用混合类型的磁盘,比如一部分磁盘是NVME SSD,一部分是SATA HDD。如果针对某些业务需要高速磁盘SSD,而某些业务 HDD 就可以满足部署,在创建资源池 Pool 的时候可以指定它创建在某些OSD 设备上。例如,Ceph 进阶系列(三):谈谈 Ceph Cache Tier 的配置 、原理 和 源码分析 里的 Cache Pool。
二、如何让某个 pool使用特定的OSD设备:
1. 在指定的 OSD 设备上创建 Pool 的方法概叙:
- 修改Ceph集群的 crush map (可以导出crush map文件修改,然后导入生效)里的 rule section,该rule 选择哪个bucket路径 (实际上就是最终选择哪个osd device,root->host->osd device)
- 通过设定Pool的crush_ruleset 来指定该 Pool 使用crush map里的哪个rule(命令:ceph osd pool set <poolname> crush_ruleset 4)
2. 纯手工步骤分解(7步):
如下图的Ceph集群,osd.0和osd.1的物理介质为 SSD, 而osd.2和osd.3的物理介质为 HDD
~/tmp$ ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.06798 root default
-3 0.02899 host ubuntu
0 ssd 0.00999 osd.0 up 1.00000 1.00000
1 ssd 0.01900 osd.1 up 1.00000 1.00000
-5 0.03899 host ubuntu-sebre
2 hdd 0.01900 osd.2 up 1.00000 1.00000
3 hdd 0.01900 osd.3 up 1.00000 1.00000
1 从Ceph集群里导出crush map
命令:ceph osd getcrushmap -o {compiled-crushmap-filename}
~$ ceph osd getcrushmap -o ./tmp/crushmap.ori
2 反编译crush map
命令:crushtool -d {compiled-crushmap-filename} -o {decompiled-crushmap-filename}
~/tmp$ crushtool -d crushmap.ori -o decrushmap.ori
3 修改crush map的#rules
我们可以看到导出来的crush map 如下,其中bucket host ubuntu包含了两个osd devices(osd.0和osd.1),而host ubuntu-sebre包含了另两个osd devices(osd.2和osd.3)。关于crush map的语法,可以参考:《ceph设计原理与实现》和 《ceph源码分析》
# begin crush map
tunable choose_local_tries 0
tunable choose_local_fallback_tries 0
tunable choose_total_tries 50
tunable chooseleaf_descend_once 1
tunable chooseleaf_vary_r 1
tunable chooseleaf_stable 1
tunable straw_calc_version 1
tunable allowed_bucket_algs 54
# devices
device 0 osd.0 class ssd
device 1 osd.1 class ssd
device 2 osd.2 class hdd
device 3 osd.3 class hdd
# types
type 0 osd
type 1 host
type 2 chassis
type 3 rack
type 4 row
type 5 pdu
type 6 pod
type 7 room
type 8 datacenter
type 9 region
type 10 root
# buckets
host ubuntu {
id -3 # do not change unnecessarily
id -4 class ssd # do not change unnecessarily
# weight 0.029
alg straw2
hash 0 # rjenkins1
item osd.0 weight 0.010
item osd.1 weight 0.019
}
host ubuntu-sebre {
id -5 # do not change unnecessarily
id -6 class ssd # do not change unnecessarily
# weight 0.039
alg straw2
hash 0 # rjenkins1
item osd.2 weight 0.019
item osd.3 weight 0.019
}
root default {
id -1 # do not change unnecessarily
id -2 class ssd # do not change unnecessarily
# weight 0.068
alg straw2
hash 0 # rjenkins1
item ubuntu weight 0.029
item ubuntu-sebre weight 0.039
}
# rules
rule replicated_rule {
id 0
type replicated
min_size 1
max_size 10
step take default
step chooseleaf firstn 0 type host
step emit
}
所以我们可以在rules部分添加如下两个rule 规则:rule ssd使用SSD的两个OSD设备,而rule hdd可以使用HDD的两个OSD设备
rule ssd{
id 1
type replicated
min_size 1
max_size 10
step take ubuntu
step chooseleaf firstn 0 type osd
step emit
}
rule hdd{
id 2
type replicated
min_size 1
max_size 10
step take ubuntu-sebre
step chooseleaf firstn 0 type osd
step emit
}
4 编译crush map
命令:crushtool -c {decompiled-crushmap-filename} -o {compiled-crushmap-filename}
[root@ceph-admin getcrushmap]# crushtool -c decrushmap.new -o crushmap.new
5 导入自定义的 crush map 到Ceph 集群
命令:ceph osd setcrushmap -i {compiled-crushmap-filename}
~/tmp$ ceph osd setcrushmap -i ./crushmap.new
10
查看导入后的crush map
$ ceph osd crush rule ls
replicated_rule
ssd
hdd
6 创建资源池pool
~/tmp$ ceph osd pool create ssd_pool 8 8
pool 'ssd_pool' created
~/tmp$ ceph osd pool create hdd_pool 8 8
pool 'hdd_pool' created
//查看刚创建好的Pool
~/tmp$ ceph osd dump|grep pool
pool 18 'ssd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 8 pgp_num 8 last_change 196 flags hashpspool stripe_width 0
pool 19 'hdd_pool' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 8 pgp_num 8 last_change 199 flags hashpspool stripe_width 0
注意:刚刚创建的两个资源池ssd_pool 和stat_pool 的 crush_ruleset 都是0,下面需要修改。
7 修改资源池pool的存储规则
# luminus 版本设置pool规则的语法:ceph osd pool set <pool name> crush_rule <rule name>
~/tmp$ ceph osd pool set ssd_pool crush_rule ssd
set pool 18 crush_rule to ssd
~/tmp$ ceph osd pool set hdd_pool crush_rule hdd
set pool 19 crush_rule to hdd
查看修改后,ssd_pool 和 hdd_pool的配置,如下,两个pool已经变更为对应的rule
~/tmp$ ceph osd dump|grep pool
pool 18 'ssd_pool' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 8 pgp_num 8 last_change 203 flags hashpspool stripe_width 0
pool 19 'hdd_pool' replicated size 3 min_size 2 crush_rule 2 object_hash rjenkins pg_num 8 pgp_num 8 last_change 206 flags hashpspool stripe_width 0
设置pool的rule,更早版本的命令格式是:ceph osd pool set ssd_pool crush_ruleset 1
到此,这个Ceph集群的OSD 使用规则就已经建立好了。sdd_pool 使用SSD OSD 类型的设备,而hdd_pool则使用HDD OSD 类型的设备。
三、测试Crush Map的rule 规则:
可以使用crushtool 来测试crush map 里的各个 rule,命令格式为:crushtool -i <compiled-crushmap-filename> --test --min-x <num> --max-x <num> --num-rep <num> --ruleset <num> --show_mappings
参数说明:
-i compiled-crushmap-filename:指定要操作的crushmap 文件,可以为编译好的/或者导出来的 crush map 文件
--test:该操作为测试模式
--min-x: 该操作起始号
--max-x:该操作结束号
--num-rep: 副本数
--ruleset: 使用哪个rule
--show_mappings: 显示使用的OSD 设备列表
如下,mapping显示[0,1] 和 [1,0],说明 ruleset 1只使用了osd.0 和 osd.1
$ crushtool -i crushmap --test --min-x 3 --max-x 10 --num-rep 2 --ruleset 1 --show_mappings
CRUSH rule 1 x 3 [0,1]
CRUSH rule 1 x 4 [1,0]
CRUSH rule 1 x 5 [0,1]
CRUSH rule 1 x 6 [1,0]
CRUSH rule 1 x 7 [1,0]
CRUSH rule 1 x 8 [1,0]
CRUSH rule 1 x 9 [1,0]
CRUSH rule 1 x 10 [0,1]