CRUSH Maps

所述CRUSH算法确定如何存储和通过计算数据存储位置检索数据。CRUSH使Ceph客户端能够直接与OSD通信,而不是通过集中式服务器或代理进行通信。通过算法确定的存储和检索数据的方法,Ceph避免了单点故障,性能瓶颈以及对其可扩展性的物理限制。

CRUSH映射包含OSD列表,用于将设备聚合到物理位置的“存储桶”列表以及告诉CRUSH如何在Ceph集群池中复制数据的规则列表。通过反映安装的底层物理组织,CRUSH可以对相关设备故障的潜在来源进行建模(从而解决)。典型的来源包括物理邻近度,共享的电源和共享的网络。通过将此信息编码到群集图中,CRUSH放置策略可以在不同故障域之间分离对象副本,同时仍保持所需的分布。例如,为了解决并发故障的可能性,可能需要确保数据副本位于使用不同架子,机架,电源,控制器和/或物理位置的设备上。

部署OSD时,它们会自动放置在CRUSH映射中的host节点下,该 节点的名称是运行它们的主机的主机名。这与默认的CRUSH故障域结合在一起,可确保副本或擦除代码碎片在主机之间是分开的,并且单个主机故障不会影响可用性。但是,对于较大的群集,管理员应仔细考虑他们对故障域的选择。

CRUSH结构

粗略地说,CRUSH映射由描述群集物理拓扑的层次结构和一组规则定义,这些规则定义了有关如何将数据放置在这些设备上的策略。层次结构ceph-osd在叶子上具有设备(守护程序),以及与其他物理功能或分组相对应的内部节点:主机,机架,行,数据中心等。规则描述了如何按照该层次结构放置副本(例如,“不同机架中的三个副本”)。

手动编辑crush结构

来理解crush中devices,types,buckets,rules这四个主要模块:

获取一个CRUSH MAP
[ceph@ceph03 ~]$ ceph osd getcrushmap -o crushmap.map        #输出为二进制的文件
反编译CRUSH MAP
[ceph@ceph03 ~]$ crushtool -d crushmap.map -o crushmap.txt     #把二进制文件转为文本文件,方便修改
重新编译一个CRUSH MAP
[ceph@ceph03 ~]$ crushtool -c crushmap.txt -o crushmap.map
设置CRUSH MAP
ceph osd setcrushmap -i crushmap.map

这里看一下crushmap.txt里面的内容:

[ceph@ceph03 ~]$ cat crushmap.txt                         
# 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

#设备还可以具有与它们关联的设备类(例如 hdd或ssd),从而可以通过crush规则方便地将它们作为目标。
# 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

#要将存储桶类型添加到CRUSH映射中,请在存储桶类型列表下创建新行。输入,type后跟唯一的数字ID和存储桶名称。
# 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 zone
type 10 region
type 11 root

#创建存储桶层次结构的目的是通过叶子节点的故障域(例如上面的host,rack,row,room等)隔离叶子节点。
# buckets
host ceph06 {                     #这里是声明为主机存储桶,当然还可以声明为rack(机架)等类型的存储桶。
        id -3           # do not change unnecessarily
        id -4 class hdd         # do not change unnecessarily
        # weight 0.078
        alg straw2                #存储桶类型,默认为straw2,还有uniform,list,tree,straw这四种
        hash 0                    # rjenkins1
        item osd.0 weight 0.039   #osd所占的权重
        item osd.3 weight 0.039
}
host ceph04 {
        id -5           # do not change unnecessarily
        id -6 class hdd         # do not change unnecessarily
        # weight 0.039
        alg straw2
        hash 0  # rjenkins1
        item osd.1 weight 0.039
}
host ceph05 {
        id -7           # do not change unnecessarily
        id -8 class hdd         # do not change unnecessarily
        # weight 0.039
        alg straw2
        hash 0  # rjenkins1
        item osd.2 weight 0.039
}
root default {                      #这里是声明为root的存储桶,root下面可以再细分为rack等类型的存储桶。
        id -1           # do not change unnecessarily
        id -2 class hdd         # do not change unnecessarily
        # weight 0.156
        alg straw2
        hash 0  # rjenkins1
        item ceph06 weight 0.078
        item ceph04 weight 0.039
        item ceph05 weight 0.039
}

####这里举个例,如果不要root类型的,改声明为rack类型的如何设置。
rack rack1 {
        id -1
        alg straw2
        hash 0
        item ceph06 weight 0.078
        item ceph04 weight 0.039
        item ceph05 weight 0.039
}

# rules
rule replicated_rule {
        id 0
        type replicated               #描述存储驱动器(复制)或RAID的规则。这里是复制
        min_size 1                    #如果池中的副本数量少于此数量,则CRUSH将不会选择此规则
        max_size 10                   #如果池中的副本数量超过此数量,则CRUSH将不会选择此规则
        step take default             #取一个存储桶名称,然后开始遍历树。
        step chooseleaf firstn 0 type host
#step chooseleaf firstn {num} type {bucket-type}即selects a set of buckets of {bucket-type}
#firstn是控制在CRUSH映射中标记了项目(OSD)时CRUSH使用的替换策略,replicated用firstn,erasure用indep
#If {num} == 0, choose pool-num-replicas buckets (all available).
#If {num} > 0 && < pool-num-replicas, choose that many buckets.
#If {num} < 0, it means pool-num-replicas - {num}.
        step emit
}
rule erasure-code {
        id 2
        type erasure
        min_size 3
        max_size 3
        step set_chooseleaf_tries 5
        step set_choose_tries 100
        step take default
        step chooseleaf indep 0 type host
        step emit                     #输出当前值并清空堆栈。
}

通过解读上面的配置文件我们对crush map有了一定的了解,我们用图再来理解一下buckets,如下图,rack类型存储桶下有host类型的存储桶,host下包含着osd类型的bucket。

DEVICE CLASSES

每个设备可以选择具有与之关联的类。默认情况下,OSD在启动时会根据其支持的设备类型自动将其类设置为 hdd,ssd或nvme。
可以使用以下命令显式设置一个或多个OSD的设备类:

ceph osd crush set-device-class <class> <osd-name> [...]

设置设备类别后,除非使用以下方法取消设置旧类别,否则无法将其更改为另一个类别:

ceph osd crush rm-device-class <osd-name> [...]

例:

[ceph@ceph03 ~]$ ceph osd crush set-device-class ssd osd.0
Error EBUSY: osd.0 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
[ceph@ceph03 ~]$ ceph osd crush rm-device-class osd.0
done removing class of osd(s): 0
[ceph@ceph03 ~]$ ceph osd tree
ID CLASS WEIGHT  TYPE NAME       STATUS REWEIGHT PRI-AFF 
-1       0.15636 root default                            
-5       0.03909     host ceph04                         
 1   hdd 0.03909         osd.1       up  1.00000 1.00000 
-7       0.03909     host ceph05                         
 2   hdd 0.03909         osd.2       up  1.00000 1.00000 
-3       0.07817     host ceph06                         
 0       0.03908         osd.0       up  1.00000 1.00000 
 3   hdd 0.03909         osd.3       up  1.00000 1.00000 
[ceph@ceph03 ~]$ ceph osd crush set-device-class ssd osd.0
set osd(s) 0 to class 'ssd'
[ceph@ceph03 ~]$ ceph osd tree
ID CLASS WEIGHT  TYPE NAME       STATUS REWEIGHT PRI-AFF 
-1       0.15636 root default                            
-5       0.03909     host ceph04                         
 1   hdd 0.03909         osd.1       up  1.00000 1.00000 
-7       0.03909     host ceph05                         
 2   hdd 0.03909         osd.2       up  1.00000 1.00000 
-3       0.07817     host ceph06                         
 3   hdd 0.03909         osd.3       up  1.00000 1.00000 
 0   ssd 0.03908         osd.0       up  1.00000 1.00000 

这使管理员可以设置设备类,而无需在OSD重新启动时或通过其他脚本更改类。
可以使用以下方式创建针对特定设备类别的放置规则:

ceph osd crush rule create-replicated <rule-name> <root> <failure-domain> <class>

然后可以将池更改为在以下情况下使用新规则:

ceph osd pool set <pool-name> crush_rule <rule-name>

修改CRUSH MAP

添加/移动OSD
ceph osd crush set {name} {weight} root={root} [{bucket-type}={bucket-name} ...]
  • name:OSD的全名,例:osd.0

  • weight:OSD的CRUSH权重,通常以太字节(TB)为单位。例:2.0

  • root:OSD所在树的根节点(通常为default),例:root=default

  • bucket-type:您可以在CRUSH层次结构中指定OSD的位置,例:datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1

举例:

ceph osd crush set osd.0 1.0 root=default datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1
调整OSD权重
ceph osd crush reweight {name} {weight}
删除OSD
ceph osd crush remove {name}
添加一个桶
ceph osd crush add-bucket {bucket-name} {bucket-type}

#例:
ceph osd crush add-bucket rack12 rack
移动桶

要将存储桶移动到CRUSH地图层次结构中的其他位置或位置,请执行以下操作:

ceph osd crush move {bucket-name} {bucket-type}={bucket-name}, [...]
删除桶
ceph osd crush remove {bucket-name}
为复制池创建规则

对于复制池,创建CRUSH规则时的主要决策是故障域的类型。例如,如果选择的故障域host,则CRUSH将确保数据的每个副本都存储在不同的主机上。如果rack 选择,则每个副本将存储在不同的机架中。

还可以创建一个规则,将数据放置位置限制为特定类别的设备。默认情况下,Ceph OSD会根据所使用设备的基础类型自动将其自身分类为hdd或ssd。这些类也可以自定义。
要创建复制规则,请执行以下操作:

ceph osd crush rule create-replicated {name} {root} {failure-domain-type} [{class}]

name:规则名称
root:应在其下放置数据的节点的名称。例:default
failure-domain-type:我们应在其中分离副本的CRUSH节点的类型。例:rack
class:设备类别数据应放在上面。例:ssd

删除规则
ceph osd crush rule rm {rule-name}
查看规则
ceph osd crush rule ls

可以使用以下方法查看规则的内容:

ceph osd crush rule dump

划分故障域

原文转载:https://blog.csdn.net/qq_33218245/java/article/details/103312942
1.目标
希望创建2个存储池,一个全hhd作为后端存储,一个全ssd作为后端存储池的高速缓存池,并且当有个别服务器宕机时,依然不影响数据的读写。

2.规划
创建两个root(hhd,ssd),6个host(node1_hhd,node2_hhd,node3_hhd,node1_ssd,node2_ssd,node3_ssd),最后将每个服务器对应的osd加入到crush中。

3.创建crush

ceph osd crush add-bucket hhd root
ceph osd crush add-bucket ssd root
ceph osd crush add-bucket node1_hhd host
ceph osd crush add-bucket node2_hhd host
ceph osd crush add-bucket node3_hhd host
ceph osd crush add-bucket node1_ssd host
ceph osd crush add-bucket node2_ssd host
ceph osd crush add-bucket node3_ssd host

4.移动crush

ceph osd crush move node1_hhd root=hhd
ceph osd crush move node2_hhd root=hhd
ceph osd crush move node3_hhd root=hhd
ceph osd crush move node1_ssd root=ssd
ceph osd crush move node2_ssd root=ssd
ceph osd crush move node3_ssd root=ssd

5.创建并移动osd crush
这里需要计算osd权重,权重计算公式(权重=osd大小%1T),如果osd大小为500G,权重就是0.50000,osd大小为2T,权重就是2.00000,我这里为了方便将osd权重全设为1.0000。

ceph osd crush create-or-move osd.0 1.00000 host=node1_hhd
ceph osd crush create-or-move osd.1 1.00000 host=node2_hhd
ceph osd crush create-or-move osd.2 1.00000 host=node3_hhd
ceph osd crush create-or-move osd.3 1.00000 host=node1_ssd
ceph osd crush create-or-move osd.4 1.00000 host=node2_ssd
ceph osd crush create-or-move osd.5 1.00000 host=node3_ssd

6.创建rule

ceph osd crush rule create-simple hhd_rule host hhd
ceph osd crush rule create-simple ssd_rule host ssd

7、创建存储池

ceph osd pool create hhd 64 64
ceph osd pool create ssd 64 64

8、给存储池指定rule

ceph osd pool set hhd crush_rule hhd_rule
ceph osd pool set ssd crush_rule ssd_rule
文档更新时间: 2020-06-02 12:01   作者:子木