CRUSH Rule基础

CRUSH Rule

CRUSH Rule就提供了一种方式,即通过用户定义的规则来指导CRUSH算法的具体执行。其场景主要如下所示。

  • 数据备份的数量:规则需要指定能够支持的备份数量。
  • 数据备份的策略:通常来说,多个数据副本是不需要有顺序的;但是纠删码不一样,纠删码的各个分片之间是需要有顺序的。所以CRUSH算法需要了解各个关联的副本之间是否存在顺序性。
  • 选择存储设备的类型:规则需要能够选择不同的存储设备类型来满足不同的需求,比如高速、昂贵的固态硬盘类型设备,或者低速、廉价的硬盘驱动器类型设备。
  • 确定失效域:为了保证整个存储集群的可靠性,规则需要根据CRUSH Map中的设备组织结构选择不同的失效域,并依次执行CRUSH算法。

Ceph集群通常能够自动生成默认的规则,但是默认规则只能保证集群数据备份在不同的主机中。实际情况往往更加精细和复杂,这就需要用户根据失效域自行配置规则,保存在CRUSH Map中,代码如下:

//CRUSH Rule的定义
rule <规则名称>
{
    ruleset <唯一的规则ID>
    type <备份策略:replicated/erasure>
    min_size <规则支持的最少备份数量>
    max_size <规则支持的最多备份数量>
    
    //选择设备范围,确定失效域
    step take ...
    step choose ...
    ......
    step emit
}

其中,规则能够支持的备份数量是由min_size和max_size确定的, type确定了规则所适用的备份策略。Ceph在执行CRUSH算法时,会通过ruleset对应的唯一ID来确定具体执行哪条规则,并通过规则中定义的step来选择失效域和具体的设备。
所有规则的详细定义如下:

ceph osd crush rule dump

CRUSH Rule的step take与step emit
CRUSH Rule执行步骤中的第一步和最后一步分别是step take与step emit。step take通过桶名称来确定规则的选择范围,对应CRUSH Map中的某一个子树。同时,也可以选择Device Class来确定所选择的设备类型,如固态硬盘或硬盘驱动器,CRUSH算法会基于对应的Shadow CRUSH Map来执行接下来的step choose。
step take的具体定义如下:

step take <桶名称> [class <Device Class>]

step emit非常简单,即表示步骤结束,输出选择的位置。

step choose与CRUSH算法原理
CRUSH Rule的中间步骤为step choose,其执行过程即对应CRUSH算法的核心实现。每一step choose需要确定一个对应的失效域,以及在当前失效域中选择子项的个数。由于数据备份策略的不同(如镜像与纠删码),step choose还要确定选择出来的备份位置的排列策略。其定义如下:

step <选择方式: choose/chooseleaf>
<选择备份的策略: firstn/indep>
<选择个数: n>
type <失效域所对应的Bucket Class>

此外,CRUSH Map中的桶定义也能影响CRUSH算法的执行过程。例如,CRUSH算法还需要考虑桶中子项的权重来决定它们被选中的概率,同时,在OSD Map中的运行状态发生变化时,尽量减少数据迁移。具体的子元素选择算法是由桶定义里面的Bucket Type来确定的。
桶定义还能决定CRUSH算法在执行时所选择的哈希算法。哈希算法往往会导致选择冲突的问题。类似地,当哈希算法选择出OSD设备后,可能会发现其在OSD Map被标记为不正常的运行状态。这时,CRUSH算法需要有自己的一套机制来解决选择冲突和选择失败问题。
1)选择方式、选择个数与失效域
在step的配置中,可以定义在当前步骤下选择的Bucket Class,即失效域,以及选择的具体个数n。例如,让数据备份分布在不同的机架中,代码如下:

step take root
step chooseleaf firstn/indep 0 type rack
step emit

或者是让数据分布在两个电源下面的两个主机中,代码如下:

step take root
step choose firstn/indep 2 type power
step chooseleaf firstn/indep 2 type host
step emit

其中,当选择个数n的值为0时,表示选择与备份数量一致的桶;当n的值为负数时,表示选择备份数量减去n个桶;当n的值为正数时,即选择n个桶。
chooseleaf可以被看作choose的一种简写方式,它会在选择完指定的Bucket Class继续递归直到选择出OSD设备。例如,让数据备份分布在不同的机架的规则也可以写成:

step take root
step choose firstn/indep 0 type rack
step choose firstn/indep 1 type osd
step emit

2)选择备份的策略:firstn与indep
CRUSH算法的选择策略主要和备份的方式有关。 firstn 对应的是以镜像的方式备份数据。镜像备份的主要特征是各数据备份之间是无顺序的,即当主要备份失效时,任何从属备份都可以转为主要备份来进行数据的读写操作。其内部实现可以理解为CRUSH算法维护了一个基于哈希算法选择出来的设备队列,当一个设备在OSD Map中标记为失效时,该设备上的备份也会被认为失效。这个设备会被移出这个虚拟队列,后续的设备会作为替补。firstn的字面意思是选出虚拟队列中前n个设备来保存数据,这样的设计可以保证在设备失效和恢复时,能够最小化数据迁移量。
而indep对应的是以纠删码的方式来备份数据的。纠删码的数据块和校验块是存在顺序的,也就是说它无法像firstn一样去替换失效设备,这将导致后续备份设备的相对位置发生变化。而且,在多个设备发生临时失效后,无法保证设备恢复后仍处于原来的位置,这就会导致不必要的数据迁移。indep通过为每个备份位置维护一个独立的( Independent )虚拟队列来解决这个问题。这样,任何设备的失效就不会影响其他设备的正常运行了;而当失效设备恢复运行时,又能保证它处于原来的位置,降低了数据迁移的成本。
虚拟队列是通过计算索引值来实现的。简单来讲,对于firstn策略,当第2个设备b (索引值为2)失效时,第2个镜像位置会重新指向索引值为2+1的设备,即第r个镜像位置会指向索引值为r+f的设备,其中f为前序失效设备的个数。而对于indep策略,当第2个设备b失效时,第2个镜像位置会指向索引值为2+1x6的设备h,也就是说,第r个镜像位置会指向索引值为r+f*n的设备,其中f为设备失效计数, n为总备份数。其精确的算法描述可以参考CRUSH论文。
3)选择桶的子元素的方式: Bucket Type
CRUSH算法在确定了最终选择的索引值后,并不是按照索引值从对应的桶中直接选出子桶或子设备的,而是提供了多个选择,让用户能够根据不同情况进行配置。子元素的选择算法通过Bucket Type来配置,分别有Uniform, List,Tree,Straw/Straw2 5种。它们各自有不同的特性,可以在算法复杂度、对集群设备增减的支持,以及对设备权重的支持3个维度进行权衡。

UniformListTreeStraw/Straw2
查找O(1)O(n)O(logn)O(n)
添加PoorOptimalGoodOptimal
删除PoorPoorGoodOptimal

根据Bucket Type的算法实现可以将子元素的选择算法分为三大类。首先是Uniform,它假定整个集群的设备容量是均匀的,并且设备数量极少变化。它不关心子设备中配置的权重,直接通过哈希算法将数据均匀分布到集群中,所以也拥有最快的计算速度O(1),但是其适用场景极为有限。
其次是分治算法。List会逐一检查各个子元素,并根据权重确定选中对应子元素的概率,拥有O(n)的复杂度,优点是在集群规模不断增加时能够最小化数据迁移,但是在移除旧节点时会导致数据重新分布。Tree使用了二叉搜索树,让搜索到各子元素的概率与权重一致。它拥有O(logn)的算法复杂度,并且能够较好地处理集群规模的增减。但是Tree 算法在Ceph实现中仍有缺陷,已经不再推荐使用。
分治算法的问题在于各子元素的选择概率是全局相关的,所以子元素的增加、删除和权重的改变都会在一定程度上影响全局的数据分布,由此带来的数据迁移量并不是最优的。第三类算法的出现即为了解决这些问题。Straw会让所有子元素独立地互相竞争,类似于抽签机制,让子元素的签长基于权重分布,并引人一定的伪随机性,这样就能解决分治算法带来的问题。Straw的算法复杂度为O(n),相对List时会稍长,但仍是可以被接受的,甚至成为了默认的桶类型配置。然而, Straw并没有能够完全解决最小数据迁移量问题,这是因为子元素签长的计算仍然会依赖于其他子元素的权重。Straw2的提出解决了Straw存在的问题,在计算子元素签长时不会依赖于其他子元素的状况,保证数据分布遵循权重分布,并在集群规模变化时拥有最佳的表现。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值