Ceph运维存储 Crush tree构建与故障域
crush规则配置
故障域架构图

树形结构图
1. 命令生成osd树形结构
1. 查看当前的树形结构,默认故障域节点为host服务器 ceph osd tree 2. 创建数据中心datacenter0 ceph osd crush add-bucket datacenter0 datacenter 3. 创建机房room0 ceph osd crush add-bucket room0 room 4. 创建机架rack0,rack1,rack2 ceph osd crush add-bucket rack0 rack ceph osd crush add-bucket rack1 rack ceph osd crush add-bucket rack2 rack 5. 把机房room0移动到数据中心datacencter0下 ceph osd crush move room0 datacenter=datacenter0 6. 把机架rack0、rack1、rack2移动到机房room0下 ceph osd crush move rack0 room=room0 ceph osd crush move rack1 room=room0 ceph osd crush move rack2 room=room0 7. 把osd01移动到: datacenter0/room0/rack0下 ceph osd crush move osd01 datacenter=datacenter0 room=room0 rack=rack0 8. 把osd02移动到: datacenter0/room0/rack1下 ceph osd crush move osd02 datacenter=datacenter0 room=room0 rack=rack1 9. 把osd03移动到: datacenter0/room0/rack2下 ceph osd crush move osd03 datacenter=datacenter0 room=room0 rack=rack2 10. 把数据中心datacencter0移动到root下 ceph osd crush move datacenter0 root=default # root属于最顶级,必须存在 11. 查看当前的树形结构 ceph osd tree #ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF # -1 0.17537 root default # -9 0.17537 datacenter datacenter0 # -10 0.17537 room room0 # -11 0.05846 rack rack0 # -3 0.05846 host osd01 # 0 hdd 0.01949 osd.0 up 1.00000 1.00000 # 1 hdd 0.01949 osd.1 up 1.00000 1.00000 # 2 hdd 0.01949 osd.2 up 1.00000 1.00000 # -12 0.05846 rack rack1 # -5 0.05846 host osd02 # 3 hdd 0.01949 osd.3 up 1.00000 1.00000 # 4 hdd 0.01949 osd.4 up 1.00000 1.00000 # 5 hdd 0.01949 osd.5 up 1.00000 1.00000 # -13 0.05846 rack rack2 # -7 0.05846 host osd03 # 6 hdd 0.01949 osd.6 up 1.00000 1.00000 # 7 hdd 0.01949 osd.7 up 1.00000 1.00000 # 8 hdd 0.01949 osd.8 up 1.00000 1.00000 - 权重关系如下: osd相加为host的权重; host相加为rack的权重; rack相加为room的权重; datacenter相加为root的权重。
修改crushmap信息
1.导出crushmap(crush算法的配置文件)
我们可以通过命令导出集群当前的crushmap信息,crushmap文件默认是二进制形式的。
1. 把二进制格式的crushmap导出到test.bin文件中 ceph osd getcrushmap -o test.bin 2. 用crushtool工具把test.bin里的二进制文件数据转换成文本形式保存草test.txt文档里 crushtool -d test.bin -o test.txt
2. 修改crush规则
1. 修改crush规则 vim test.txt # tunable:这里都是一些微调的参数,通常不建议修改 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 # device:这里将列出集群中的所有OSD基本信息 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 device 6 osd.6 class hdd device 7 osd.7 class hdd device 8 osd.8 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 # 区域(华东1,华东2等) type 10 root # 最顶级,必须存在 # buckets:这里就是定义故障域名。 host osd01 { id -3 # do not change unnecessarily id -4 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd.0 weight 1.000 # 将osd.0的权重设置为1.000 item osd.1 weight 1.000 # 将osd.1的权重设置为1.000 item osd.2 weight 1.000 # 将osd.2的权重设置为1.000 } rack rack0 { id -11 # do not change unnecessarily id -16 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd01 weight 3.000 # osd01主机的权重为3.000(osd01主机上的osd daemon节点权重相加) } host osd02 { id -5 # do not change unnecessarily id -6 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd.3 weight 1.000 # 将osd.3的权重设置为1.000 item osd.4 weight 1.000 # 将osd.4的权重设置为1.000 item osd.5 weight 1.000 # 将osd.5的权重设置为1.000 } rack rack1 { id -12 # do not change unnecessarily id -15 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd02 weight 3.000 # osd02主机的权重为3.000(osd02主机上的osd daemon节点权重相加) } host osd03 { id -7 # do not change unnecessarily id -8 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd.6 weight 1.000 # 将osd.6的权重设置为1.000 item osd.7 weight 1.000 # 将osd.7的权重设置为1.000 item osd.8 weight 1.000 # 将osd.8的权重设置为1.000 } rack rack2 { id -13 # do not change unnecessarily id -14 class hdd # do not change unnecessarily # weight 0.058 alg straw2 hash 0 # rjenkins1 item osd03 weight 3.000 # osd03主机的权重为3.000(osd03主机上的osd daemon节点权重相加) } room room0 { id -10 # do not change unnecessarily id -17 class hdd # do not change unnecessarily # weight 0.175 alg straw2 hash 0 # rjenkins1 item rack0 weight 3.000 # rack0机架的权重为3(rack0机架上的host主机权重相加) item rack1 weight 3.000 # rack1机架的权重为3(rack1机架上的host主机权重相加) item rack2 weight 3.000 # rack2机架的权重为3(rack2机架上的host主机权重相加) } datacenter datacenter0 { id -9 # do not change unnecessarily id -18 class hdd # do not change unnecessarily # weight 0.175 alg straw2 hash 0 # rjenkins1 item room0 weight 9.000 # room0机房的权重为9(机房所有rack机架的权重相加) } root default { id -1 # do not change unnecessarily id -2 class hdd # do not change unnecessarily # weight 0.175 alg straw2 hash 0 # rjenkins1 item datacenter0 weight 9.000 # datacenter0数据中心的权重为9(数据中心所有room机房的权重相加) } # rules:这里定义的时存储池的规则 rule nana_rule { # 规则集的命名,创建pool时可以指定rule集 id 0 # 定义新的规则存储池的时候,id和规则集的命名都不能重复 type replicated # type为存储池的类型,replicated代表副本池(还有esurecode模式) min_size 1 # min_size代表允许的最小副本数 max_size 10 # max_size代表允许的最大副本数 step take default # 定义pg查找副本的入口点(step代表每一个步骤) step chooseleaf firstn 0 type rack # 深度优先,故障域修改成rack(默认为host). step emit # 结束 } rule dada_rule { # 规则集的命名,创建pool时可以指定rule集 id 1 # 定义新的规则存储池的时候,id和规则集的命名都不能重复 type replicated # type为存储池的类型,replicated代表副本池(还有esurecode模式) min_size 1 # min_size代表允许的最小副本数 max_size 10 # max_size代表允许的最大副本数 step take datacenter0 # 定义pg查找副本的入口点(step代表每一个步骤) step chooseleaf firstn 0 type host # 深度优先,故障域默认为host step emit # 结束 } # end crush map
3. 将修改好的crush文件重新导入ceph集群
1. 把test转换成二进制形式 crushtool -c test.txt -o new.bin 2. 将test导入集群 ceph osd setcrushmap -i new.bin 3. 查看当前的树形结构 ceph osd tree # ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF # -1 9.00000 root default # -9 9.00000 datacenter datacenter0 # -10 9.00000 room room0 # -11 3.00000 rack rack0 # -3 3.00000 host osd01 # 0 hdd 1.00000 osd.0 up 1.00000 1.00000 # 1 hdd 1.00000 osd.1 up 1.00000 1.00000 # 2 hdd 1.00000 osd.2 up 1.00000 1.00000 # -12 3.00000 rack rack1 # -5 3.00000 host osd02 # 3 hdd 1.00000 osd.3 up 1.00000 1.00000 # 4 hdd 1.00000 osd.4 up 1.00000 1.00000 # 5 hdd 1.00000 osd.5 up 1.00000 1.00000 # -13 3.00000 rack rack2 # -7 3.00000 host osd03 # 6 hdd 1.00000 osd.6 up 1.00000 1.00000 # 7 hdd 1.00000 osd.7 up 1.00000 1.00000 # 8 hdd 1.00000 osd.8 up 1.00000 1.00000
4. 修改pool池的crush_rule
重新导入集群后,需要把之前存在pool池的crush_rule都修改一下,否则集群会出现uknown状态,无法达到active+clean状态。
1. 查看已经存在的pool池 ceph osd pool ls # .rgw.root # default.rgw.control # default.rgw.meta # default.rgw.log # cephfs_data # cephfs_metadata 2. 修改pool池的crush规则 ceph osd pool set cephfs_metadata crush_rule dada_rule # set pool 6 crush_rule to dada_rule ceph osd pool set cephfs_data crush_rule dada_rule # set pool 5 crush_rule to dada_rule
crush算法设置错误故障模拟
crush算法设置错误模拟
当我们将crush算法规则设置错误的时候,ceph集群的data部分会出现unknown状态。
出现unknown,这个时候代表osd daemon是和pg对应不上的,极大可能是crush算法出现了问题。我们在生产环境中,出现这种情况一定要仔细检查crush算法的规则配置是否有误。
1. 创建一个新的数据中心datacenter1 ceph osd crush add-bucket datacenter1 datacenter 2. 创建一个root的新入口点abc ceph osd crush add-bucket abc root 3. 将数据中心datacenter1移动到root的入口点下 ceph osd crush move datacenter1 root=abc 5. 查看新入口的逻辑树结构,我们新创建的osd逻辑树结构是错误的,datacenter1下面是没有下一个层级 ceph osd tree # ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF # -20 0 root abc # -19 0 datacenter datacenter1 6. 删除原来导出的crushmap(crush算法的配置文件)test.txt和test.bin rm -rf test.txt rm -rf test.bin 7. 重新导出crushmap(crush算法的配置文件)test.txt和test.bin ceph osd getcrushmap -o test.bin crushtool -d test.bin -o test.txt 8. 在crushmap文件中添加错误的crush规则xxx_rule vim test.txt .... # 错误规则 rule xxx_rule { id 2 type replicated min_size 1 max_size 10 step take abc # root入口设置为错误入口abc step chooseleaf firstn 0 type host step emit } 9. 利用错误规则xxx_rule创建pool池 ceph osd pool create test_pool02 128 replicated xxx_rule 10. 查看所有pool池的状态 ceph osd dump # test_pool02的crush_rule的id为2 # pool 9 'test_pool02' ... crush_rule 2 ... 11. 查看ceph集群状态data部分出现了unknown ceph -s # data: # pgs: 19.048% pgs unknown # 544 active+clean # 128 unknown
crush算法设置错误问题解决
方式一: 将crush规则修改正确 1. 将pool池(test_pool02)的规则修改成正确的crush规则(nana_rule)。 ceph osd pool set test_pool02 crush_rule nana_rule # set pool 9 crush_rule to nana_rule 2. 查看ceph集群的健康状态。 ceph -s ... # data: # pgs: 672 active+clean 方式二: 删除crush规则设置错误的pool池 - 在ceph集群中,mon_allow_pool_delete此选项默认为false,表示不允许删除pool池,只有此选项打开后方可删除。 1. 修改mon_allow_pool_delete选项配置 ceph tell mon.* injectargs --mon_allow_pool_delete=true 2. 删除错误规则xxx_rule创建pool池(test_pool02) ceph osd pool rm test_pool02 test_pool02 --yes-i-really-really-mean-it 3. 查看ceph集群的健康状态。 ceph -s # data: # pgs: 544 active+clean 注意:建议使用方式一解决unknown状态问题,能不删除pool池就不要删除pool池,pool池的删除会影响集群数据的变动。
参考:https://blog.csdn.net/Yosigo_/article/details/117091692