前言:

​ 分布式存储系统需要让数据均匀的分布在集群中的物理设备上,同时在新设备加入,旧设备退出之后让数据重新达到平衡状态尤为重要。新设备加入后,数据要从不同的老设备中迁移过来。老设备退出后,数据迁移分摊到其他设备。将文件、块设备等数据分片,经过哈希,然后写入不同的设备,从而尽可能提高I/O并发与聚合带宽。

​ 在实际场景中如何通过最小数据迁移使得集群恢复平衡,如何分配备份到设备上,使得数据尽可能的安全是很重要的问题。Ceph对普通哈希函数扩展后解决了上述问题,Ceph基于哈希的数据分布算法就是CRUSH。

​ CRUSH支持副本、Raid、纠删码数据备份策略,并受控的将数据的多个备份映射到集群不同故障域的底层设备上。

straw算法

最初提供了四种基本选择算法:

​ 观察图中数据得到,unique执行效率最高,抵御结构变化能力最差,straw算法执行效率相较unique于tree要差,但是抵御结构变化的能力最强。因为数据可靠性最为重要,随着扩容引入越来越多的设备加上使用时间的推移,集群设备需要经常更换固件,因此目前基本生产环境的Ceph集群都选择straw算法。

​ straw算法为每个元素随机计算一个签长,选择签长最长的元素输出,签长越长的元素被选中的概率越大,数据落在上面的概率就越大。straw算法通过累计当前元素与前后元素的权重差值作为计算下一个元素签长的基准,因此在每次加入或删除osd时,都会引起不相干的数据迁移。后修改为签长计算仅与自身权重有关系,避免了这一现象,称为straw2算法,此算法目前为ceph的默认算法。

cluster map

​ cluster map是集群层级拓扑结构的逻辑描述形式,其简单的拓扑如:数据中心->机加->主机->磁盘,因此cluster map采用树这种数据结构。根节点root是整个集群的入口;所有叶子节点device都是真实的最小物理存储设备(磁盘);中间节点bucket可以是device的集合,也可以是低级的bucket的集合。

​ cluster map这种层级关系通过<bucket, items>这样一张二维表映射,每个bucket,都保存自身所有直接孩子的编号,即items。当items为空时,表明bucket为叶子节点。

简单图示如下,最下面的叶子节点device(如磁盘)存放数据,中间是host类型的bucket(物理主机),最上面root是集群入口:

配置示例:

host default_10.10.10.125 {			# 类型host,名字为default_10.10.10.125
id -3 # bucket的id,root与bucket的数字标识都为负值,只有device是 非负的数字标识,表明device是承载数据的真实设备。
# weight 14.126 # 权重,默认为子item的权重之和
alg straw2 # bucket的随机选择算法,这里用 straw2
hash 0 # rjenkins1 # 使用hash函数rjenkins1
item osd.0 weight 6.852 # osd.0的权重
item osd.1 weight 7.274 # osd.1的权重
}

placement rule

​ cluster map定义了存储集群的物理拓扑描述。placement rule完成数据映射,即决定一个PG的对象副本如何选择的规则,用户可自定义副本在集群中的分布。

placement rule可含有多个操作,包括以下三种类型:

  1. take:从cluster map中选择指定编号的bucket,系统默认为root类型的节点

  2. select:接收take输入的bucket,从中随机选择指定类型和数量的item。

    step [choose|chooseleaf] [firstn|indep] <Num> type <bucket-type>

    [choose|chooseleaf]:choose操作有不同的选择方式

    • choose选择出Num个类型为bucket-type的子bucket
    • chooseleaf选择出Num个类型为bucket-type的子bucket,然后递归到叶子节点选择一个OSD设备

    [firstn|indep]:ceph有两种select算法(均为深度优先遍历)。不同之处在于纠删码要求的结果是有序的,因此如果指定输出数量为4而无法满足时:

    • firstn(多副本):[1,2,4]
    • indep(纠删码):[1,2,CRUSH_ITEM_NONE,4]

    [Num] :

    • Num == 0,选出的子buket为pool设置的副本数
    • pool副本数 > Num > 0,选出的子buket为Num
    • Num < 0, 选出的子buket为pool设置的副本数减去Num的绝对值

    [type] :故障域的类型,如果为rack,保证选出的副本都位于不同机架的主机磁盘上,如果为host,则保证 选出的副本位于不同主机上。

    如果选中条目因故障、冲突等原因无法使用,则会重新执行select。

  3. emit:输出选择结果

配置示例:

rule <rulename> {

        id [a unique whole numeric ID]
type [ replicated | erasure ]
min_size <min-size>
max_size <max-size>
step take <bucket-name> [class <device-class>]
step [choose|chooseleaf] [firstn|indep] <Number> type <bucket-type>
step emit
}
rule data {
ruleset 0 //ruleset 编号
type replicated //多副本类型
min_size 1 //副本最小值为1
max_size 10 //副本最大值为10
step take default //选择default buket输入{take(default)}
step chooseleaf firstn 0 type host //选择当前副本数个主机下的OSD{select(replicas, type)}
step emit //输出将要分布的bucket的列表{emit(void)}
}

选择方式

CHRUSH算法依赖以上的算法(默认为straw2)实现对PG的映射,输入pg_id、Cluster map、Cluster rule,与随机因子经过哈希计算,输出一组OSD列表,即该pg要落在OSD的编号。

但是选出的OSD有可能会出现冲突或过载,就需要重新选择:

  1. 冲突:指选中条目已经存在于输出条目中,如osd.1已经存在于输出列表中,下一个经计算同样选出了osd.1,此时需要调整随机因子,再次计算进行选择。

  2. 过载或失效:指选出的OSD无法提供足够的空间来存储数据,虽然CRUSH算法理论上可以让数据在所有device(磁盘)中均匀分布,但实际并非如此:

    • 小规模集群,PG数量较少,则CRUSH输入的样本容量不够,导致数据计算分布不均匀。
    • crush自身对于多副本模式数据均匀分布做的不够完善。

    ceph引入过载测试reweight可人工干预对OSD的选择概率,reweight的值设置的越高,则通过测试概率越高,因此可以通过降低过载OSD的reweight和增加低负载OSD的reweight来使得数据均衡。

引入过载测试也可以区分OSD暂时失效和被永久删除

如果OSD暂时失效(如拔出对应磁盘一段时间,ceph将其设置为OUT),可以将其reweight的值设置为0.000,利用过载测试将其从候选条目中筛掉,进而将其承载的数据迁移到其他OSD。恢复后再将reweight设置为1.000,即可迁回数据(指OSD离线期间产生的新数据)

如果是被永久删除,那么它会被从候选条目删除,即便后续再次添加进来,因为cluster map中的唯一编号变化而承载与之前不同的数据,使得集群出现大规模的数据均衡。

学习自:

《Ceph源码分析》 常涛

《Ceph之RADOS设计原理与实现》 谢型果 严军

https://docs.ceph.com/docs/kraken/rados/operations/crush-map/

Ceph学习笔记(2)- CRUSH数据分布算法的更多相关文章

  1. 机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集

    机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集 关键字:FPgrowth.频繁项集.条件FP树.非监督学习作者:米 ...

  2. 机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析

    机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析 关键字:Apriori.关联规则挖掘.频繁项集作者:米仓山下时间:2018 ...

  3. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)

    机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN) 关键字:邻近算法(kNN: k Nearest Neighbors).python.源 ...

  4. [ML学习笔记] 朴素贝叶斯算法(Naive Bayesian)

    [ML学习笔记] 朴素贝叶斯算法(Naive Bayesian) 贝叶斯公式 \[P(A\mid B) = \frac{P(B\mid A)P(A)}{P(B)}\] 我们把P(A)称为"先 ...

  5. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  6. HMM模型学习笔记(前向算法实例)

    HMM算法想必大家已经听说了好多次了,完全看公式一头雾水.但是HMM的基本理论其实很简单.因为HMM是马尔科夫链中的一种,只是它的状态不能直接被观察到,但是可以通过观察向量间接的反映出来,即每一个观察 ...

  7. 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码

    一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...

  8. Ceph学习笔记(3)- Monitor

    Ceph学习笔记(3)- Monitor 前言: ​ Ceph将cluster map与placement rule合并为一张表称为crush map,作为集群表的一部分.由Monitor对集群表的副 ...

  9. 学习笔记 --- 最大流Dinic算法

    为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...

随机推荐

  1. 前端每日实战:113# 视频演示如何用纯 CSS 创作一个赛车 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/mGdXGJ 可交互视频 此视频是可 ...

  2. 大厂常问iOS面试题--多线程篇

    1.进程与线程 进程: 1.进程是一个具有一定独立功能的程序关于某次数据集合的一次运行活动,它是操作系统分配资源的基本单元. 2.进程是指在系统中正在运行的一个应用程序,就是一段程序的执行过程,我们可 ...

  3. objectarx 填充的分割

    主要思路:找到填充边界集合:vecBo,然后把面积最大的边界找出来:bo1,用分割曲线和bo1通过boundary命令构成两个新的最大封闭边界,左边的记为 boLeft(红色部分),右边的记为boRi ...

  4. 10个机器学习人工智能开发框架和AI库(优缺点对比表)/贪心学院

    概述 通过本文我们来一起看一些用于人工智能的高质量AI库,它们的优点和缺点,以及它们的一些特点. 人工智能(AI)已经存在很长时间了.然而,由于这一领域的巨大进步,近年来它已成为一个流行语.人工智能曾 ...

  5. DIY 作品 及 维修 不定时更新

    手机电池DIY充电宝 2块,优质手机电池加一个升压ic ,焊上一个 usb 母头.比买的强多了. 还能调压,最高调到24V 可以带白光焊台. 更换手机 SIM/SD 卡二合一 贴上高温胶带,吹下来. ...

  6. Java中将文件夹复制到另一个文件夹

    文件夹的拷贝*** public static void copyDir(String sourcePath, String newPath) { File start = new File(sour ...

  7. 深入学习用 Go 编写 HTTP 服务器

    Go是一门通用的编程语言,想要学习 Go 语言的 Web 开发,就必须知道如何用 Go 启动一个 HTTP 服务器用于接收和响应来自客户端的 HTTP 请求.用 Go实现一个http server非常 ...

  8. 基于Redis未授权访问的挖矿蠕虫分析

    0x01 攻击方式 利用的是通用漏洞入侵服务器并获得相关权限,从而植入挖矿程序再进行隐藏. 通过对脚本的分析,发现黑客主要是利用 Redis未授权访问漏洞进行入侵.脚本里有个python函数. imp ...

  9. $api 回调函数then应用

    getReceiveListAPI (param) { return new Promise(resolve => { let params = { // idCard: this.idCard ...

  10. 深入理解requestAnimationFrame并实现相册组件中的切换动画

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12529885.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 通常情况下,我们利 ...