CRUSH运行图调制
CRUSH:基于hash的数据分布算法,ceph集群当中独有的一种数据分布机制。
输入:对象的标识符、crush运行图crush map、归置规则Placement rule。
输出:OSD集合。
用户给定一个对象标识,CRUSH算法就能够通过计算得出这些对象将存储在那些个OSD上。
CRUSH分两步:
OBJ -> PG :一致性哈希
PG -> OSD:CRUSH算法
冗余方法有两种:副本池、纠删码池。
故障域:
无论是副本池还是纠删码池都要考虑故障域的概念,
选择OSD的时候不仅是数量,还要保证OSD垮故障域,如果故障域的级别只是OSD为目标而不管OSD来自于那些地方,OSD的容灾级别就是通过故障域来实现的。故障域可以是跨主机跨地域等。
Cluster Map五大运行图:
Monitor Map:保存当前集群的唯一标识、集群的位置、名称、地址、端口、版本等等
OSD Map:保存OSD的创建时间、存储池数量、版本、规制组、OSD自身的信息等。
PG Map:保存PG数量,状态、时间戳、占满率。
CRUSH Map:存储设备列表、故障域的树状结构、存储数据时如何你用树状结构的规则即Placement Rule、(CRUSH=故障域的树状结构+归置规则。有时会分开叫crush运行图和归置规则)。
MDS Map:当前集群metadata server的数量、活跃数、备用的、备用状态等。
上面这些包括monitor map的所有运行图都放在Monitor进程上了,各运行图维护着各自的运行状态的变更。
故障域的树状结构:
数据中心->机房->机排->机架->主机->磁盘->OSD
以OSD为故障域如果所有OSD都在一个主机上主机故障之后所有的副本就会丢失。如果以主机为故障域这几个存放副本的OSD就必须在不同的主机上。机架为故障域时几个OSD就在不同的机架上以此类推。
归置规则就是定义如何使用这个树状结构来跟好的布局树对象。树状图中的每一个节点都成为一个桶(bucket),这个bucket和OSS中的bucket是不同的东西。找OSD的时候故障域可以告诉我们这些OSD可以跨那个级别的设备。
tack:CRUSH算法搜寻OSD的起始位置,指定入口。
select:根据CSUDH算法和指定的故障域,从入口向下去挑选出符合条件的OSD集合。
副本池和纠删码池使用的不同的挑选算法:副本池:firstn、纠删码池:indep。都是深度优先算法,不过选出的OSD个数有区别。
桶算法:树结构中子项目的选择算法(一个桶当中选子项目的算法)。
uniform、list、tree、straw、straw2
Ceph集群在运行起来之后也会自己生成运行图当中的每一个bucket的定义,归置规则Placement Rule定义Ceph客户端如何选择存储桶,以及桶当中的主OSD是谁,也就是从列表当中选中谁是主OSD。管理员可以自定义归置规则,也可以让存储池自行生成归置规则。
在Ceph集群上使用归置规则和调制CRUSH:
常用命令:
ceph osd crush
获取当前运行图:
先获取crushmap的二进制:
~]$ ceph osd getcrushmap -o /tmp/mycrushmap.bin 14
再反编译成文本:
~]$ crushtool -d /tmp/mycrushmap.bin -o ./mycrushmap.txt
获取到的运行图如下:
~]$ cat mycrushmap.txt # begin crush map 可调参数,微调crush的某些特性 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 hdd device 1 osd.1 class hdd device 2 osd.2 class hdd device 3 osd.3 class hdd device 4 osd.4 class hdd device 5 osd.5 class hdd # types 支持的桶bucket类型 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 host ceph04 { id -3 # do not change unnecessarily id -4 class hdd # do not change unnecessarily # weight 0.029 alg straw2 # 桶算法 hash 0 # rjenkins1 使用哪种hash计算的类型为rjenkins1 item osd.0 weight 0.015 # host下面有两个子项目osd0和osd1,和对应的权重,根据磁盘大小做的比例计算 item osd.1 weight 0.015 } host ceph05 { id -5 # do not change unnecessarily id -6 class hdd # do not change unnecessarily # weight 0.029 alg straw2 hash 0 # rjenkins1 item osd.2 weight 0.015 item osd.3 weight 0.015 } host ceph06 { id -7 # do not change unnecessarily id -8 class hdd # do not change unnecessarily # weight 0.029 alg straw2 hash 0 # rjenkins1 item osd.4 weight 0.015 item osd.5 weight 0.015 } # 还可以定义主机的上级结构 # 如果没有下面就是跟结构 root default { id -1 # do not change unnecessarily id -2 class hdd # do not change unnecessarily # weight 0.088 alg straw2 hash 0 # rjenkins1 item ceph04 weight 0.029 # 因为是树状结构,这里没有其他结构了所以直接就是节点名称 item ceph05 weight 0.029 # 如果还有其他结构填写相应的结构即可 item ceph06 weight 0.029 } # rules 从这个树状结构当中如何选择OSD rule replicated_rule { # 这是个副本池的规则,如果创建的是纠删码池则会生成一个默认的纠删码池规则 id 0 type replicated # 冗余数据的类型方式。通过replicated冗余逻辑来存放 min_size 1 # 冗余的最小个数 max_size 10 # 冗余的最多个数,默认为3个 step take default # 开始挑选设备的位置,这里为default,就是上面的root default step chooseleaf firstn 0 type host # 深度优先遍历算法,chooseleaf:直接选择叶子节点;firstn 选择前n个;host:故障域为host step emit # 弹出结果 } # end crush map
将修改好的运行图注入回集群:
将修改好的文本文件编译成二进制:
~]$ crushtool -c mycrushmap.txt -o mycrushmap-v2.bin
将curshmap注入回集群:注入后即可生效,务必做好充分测试。
~]$ ceph osd setcrushmap -i mycrushmap-v2.bin 15