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

相关