2.2.2 CRUSH算法因子
上述介绍可以看出,CRUSH算法在 Ceph存储系统的数据寻址中占有核心地位,Ceph存储系统通过 CRUSH 算法规则来控制数据的分布策略,Ceph存储系统的 CRUSH算法能够控制对象文件在存储集群中随机均匀地分布。
CRUSH算法包含两个关键输入因子:层次化的 ClusterMap以及数据分布策略PlacementRules。
1. 层次化的 ClusterMap
层次化的 ClusterMap 反映了存储系统层级的物理拓扑结构。
Ceph存储集群通过 ClusterMap定义了 OSD守护进程的静态拓扑关系(层级信息),使得CRUSH算法在选择OSD时具备了主机、机架、机房等信息的感知能力。通过 ClusterMap规则定义,Ceph 存储系统允许数据副本可以分布在不同的主机、不同的机架,甚至不同的机房中,提高了数据存储的安全性。
ClusterMap由设备(device)和桶(bucket)组成,device是最基本的存储设备,也就是 OSD,通常 1个 OSD对应 1 个磁盘存储设备,bucket 表示存放设备的容器,可以包含多个设备或子类型的 bucket。
存储设备(device)的权重由管理员设置,以控制设备负责存储的相对数据量,device的权重值越高,对应的磁盘就会被分配写入更多的数据。大型存储系统中的存储设备(磁盘)通常存在容量大小不等或者性能高低不一的情况,系统管理员可以依据存储设备的利用率 和负载来设定权重,随机数据分布算法,以此控制数据的最终分布,实现存储系统设备的 数据量均衡,进而平衡存储系统的I/O 负载,最终提高存储集群整体的性能和可靠性。
桶的权重是它所包含的所有元素(device及 bucket)权重的总和。Bucket可以包含很多种类型,例如,Host 就代表一个主机节点,可以包含多个 device;Rack 代表机架,包含多个 host节点。Ceph中默认有 OSD、host、Chassis、Rack、row、PDU、Pod、Room、Datacenter、Region、root,共计11个层级(同时也允许用户定义自己新的类型),它们含义如下。
OSD 磁盘设备,对应 OSD守护进程
host 包含若干个 OSD的主机
Chassis 包含若干个刀片服务器的机箱
Rack 包含若干个主机的机架
row 包含若干个主机的一排机柜
PDU 为机柜分配的电源插排
Pod 一个数据中心中的机房单间
Room 含若干个机柜和主机的机房
Datacenter 包含若干机房的数据中心
Region 包含若干数据中心的区域
root bucket分层结构的根
通常 OSD、host、Rack 层级较为常用。下面举例说明 bucket的用法。
host test1{ |
|
// 类型host,名字为 test1 |
id -2 |
|
//bucket的 ID,⼀般为负值 |
#weight 3.000 |
|
// 权重,默认为⼦ item 的权重之和 |
algstraw |
|
//bucket随机选择的算法 |
hash 0 |
|
//bucket随机选择的算法使⽤的 hash函数 |
|
|
// 这⾥ 0代表使⽤ hash 函数 jenkins1 |
itemosd.1 weight |
1.000 |
//item1: osd.1 和权重 |
itemosd.2 weight |
1.000 |
|
itemosd.3 weight } |
1.000 |
|
host test2{id -3
# weight 3.00algstrawhash 0
item osd.3 weight 1.000item osd.4 weight 1.000itemosd.5 weight 1.000
}
rootdefault{ //root的类型为bucket,名字为 defaultid -1 //ID号
# weight 6.000algstraw
hash 0
item test1 weight 3.000itemtest2 weight 3.000
}
根据上面 ClusterMap的语法定义,图 2-2 给出了比较直观的层级化的树形结构。
如图2-2所示,Ceph的 ClusterMap是一个由 bucket和 device 共同组成的树形存储层次结构,叶子节点是device(也就是OSD),其他的节点称为bucket节点,这些bucket都是逻辑上的概念,是对物理结构的抽象(如对数据中心的抽象、机房的抽象、机架的抽象、主机的抽象等),树形结构只有一个最终的根节点,称为root节点,root也是一个抽象的逻辑概念。
图 2-2Ceph的CusterMap层级结构
在上面的 ClusterMap中,有一个 root类型的 bucket,名字为 default;root下面有两个 host类型的bucket,名字分别为 test1和 test2,其下分别各有3个 OSD设备,每个 device的权重都为 1.000,说明它们的容量大小都相同。host 的权重为子设备之和,即test1与test2 的权重均为3.000,它是自动计算的,不需要设置;同理,root 的权重为6.000。
2. 数据分布策略 PlacementRules
PlacementRules决定了一个 PG的对象(副本或纠删码策略)如何选择 OSD,通过这些自定义的规则,用户可以设置副本在集群中的分布。Ceph 存储系统的PlacementRules 定义格式如下。
take(a)choose
choose firstn {num} type {bucket-type}chooseleaffirstn{num} type{bucket-type}
If{num}== 0,choose pool-num-replicasbuckets (all-available).
If {num} > 0 && <pool-num-replicas,choose that many buckets.
If {num} < 0,it means pool-num-replicas- |{num}|.
Emit
PlacementRules 的执行流程如下。
(1) take操作选择一个 bucket,一般是root类型的 bucket。
(2) choose 操作有不同的选择方式,其输入都是上一步的输出。
a)choosefirstn 深度优先选择出 num个类型为 bucket-type的子 bucket。b)chooseleaf先选择出 num个类型为bucket-type的子 bucket,然后递归到叶子节
点,选择一个OSD 设备。
i. 如果 num为 0,num就为 Pool 设置的副本数;
ii. 如果 num大于 0,小于Pool 的副本数,那么就选出 num个;
iii. 如果 num小于 0,就选出 Pool 的副本数减去 num 的绝对值。
(3) emit输出结果。
由上述流程可以看出,PlacementRules主要定义以下 3个关键操作。
(1)从 CRUSHMap中的哪个节点开始查找;
(2)使用哪个节点作为故障隔离域;
(3)定位副本的搜索模式(广度优先或深度优先)。
3. 示例
(1)3 个副本分布在 1个 row 下的 3个 cabinet 中。
在图2-3中,最下面的长方形图例代表一台主机,里面的圆柱形图例代表OSD, cabinet图例代表一个机柜,row图例代表一排机柜,顶端的 root是根节点,可以把它理解成一个数据中心。
图 2-3 Ceph数据分布示意(CusterMap)
自顶而下来看,顶层是一个 rootbucket,每个 root下有 4个 row类型 bucket,每个 row下面有 4个 cabinet,每个cabinet下有若干个 OSD设备(图中有 4个 host,每个host有若干个 OSD设备,但是在本 CRUSHMap中并没有设置host这一级别的 bucket,而是直接把4个host上的所有OSD设备定义为一个cabinet)。
该场景下,PlacementRules定义如下。
rulereplicated_ruleset {
ruleset 0 //ruleset的编号ID
typereplicated //类型 replicated或者erasurecode
min_size 1 //副本数最⼩值
max_size 10 //副本数最⼤值
step take root //选择⼀个rootbucket,做下⼀步的输⼊
step choose firstn 1type row //选择⼀个 row,同⼀排
stepchoosefirstn3typecabinet //选择3个cabinet,3副本分别在不同的cabinet
stepchoosefirstn1typeosd //在上⼀步输出的3个cabinet中,分别选择⼀个OSD
stepemit
}
根据上面的 ClusterMap和 PlacementRules 定义,选择算法的执行过程如下。1)选中 rootbucket作为下一个步骤的输入;
2) 从 root类型的 bucket中选择 1个 row类的子 bucket,其选择的算法在 root的定义中设置,一般设置为 straw算法;
3)从上一步的输出row中,选择 3个 cabinet,其选择的算法在 row中定义;4)从上一步输出的3个 cabinet中,分别选出一个 OSD,并输出。
最终实现效果为可选择出3个OSD 设备,分布在1个row上的 3个 cabinet中。
(2) 主副本分布在 SSD 上,其他副本分布在 HDD上。
如图 2-4所示的 ClusterMap定义了 2个 root类型的 bucket,一个是名为SSD的root类型的 bucket,其 OSD存储介质都是SSD固态硬盘,它包含 2个 host,每个host上的存储设备都是 SSD固态硬盘;另一个是名为 HDD的 root类型的bucket,其 OSD存储介质都是 HDD硬盘,它有 2个 host,每个host上的设备都是 HDD硬盘。
图 2-4Ceph数据分布示意(CusterMap)
该场景下,PlacementRules定义如下。
rule ssd-primary {
ruleset 0
type replicatedmin_size 1
max_size10
step take ssd //选择SSD这个rootbucket为输⼊step chooseleaf firstn 1 type host //选择⼀个host,并递归选择叶⼦节点 OSDstep emit //输出结果
step take hdd //选择HDD这个rootbucket为输⼊
step chooseleaf firstn -1 type host //选择总副本数减⼀个host
//并分别递归选择⼀个叶⼦节点OSD
step emit //输出结果
}
根据上面的 ClusterMap和 PlacementRules 定义,选择算法的执行过程如下。1)首先 take操作选择 ssd为 root类型的 bucket;
2) 在 SSD的 root中先选择一个 host,然后以该 host 为输入,递归至叶子节点,选择一个 OSD设备;
3)输出选择的设备,也就是SSD设备;
4)选择 HDD作为 root的输入;
5) 选择2个host(副本数减1,默认3副本),并分别递归选择一个OSD设备,最终选出 2个 HDD设备;
6)输出最终结果。
最终实现效果为输出 3个设备,一个是 SSD类型的磁盘,另外两个是 HDD磁盘。通过上述规则,就可以把PG的主副本存储在SSD类型的 OSD上,其他副本分布在HDD类型的磁盘上。