一致性hash算法和CEPH CRUSH

一致性hash算法和CEPH CRUSH

         Ceph之CRUSH算法讨论了一上午,来记录下自己的收获。最大的收获就是一致性hash算法的学习,最后再补充下对ceph的认识。

最后有参考的文章啊,目的是学习,如有侵权,请联系,谢谢。

1.  一致性hash算法

一致性hash算法是一种数据分布算法,数据分布算法至少需要考虑三点:

1)故障域隔离。同份数据的不同副本分布在不同的故障域,降低数据损坏的风险;
2) 负载均衡。数据能够均匀地分布在磁盘容量不等的存储节点,避免部分节点空闲部分节点超载,从而影响系统性能;
3) 控制节点加入离开时引起的数据迁移量。当节点离开时,最优的数据迁移是只有离线节点上的数据被迁移到其它节点,而正常工作的节点的数据不会发生迁移。

1.1 为什么要有一致性hash算法

         假设数据为x,存储节点数目为N。将数据分布到存储节点的最直接做法是,计算数据x的Hash值,并将结果同节点数目N取余数,余数就是数据x的目的存储节点。即目的存储节点为 Hash(x)% N。对数据计算Hash值的目的为了可以让数据均匀分布在N个节点中。这种做法的一个严重问题是,当加入新节点或则节点离开时,几乎所有数据都会受到影响,需要重新分布。因此,数据迁移量非常大。

       原因就是添加一个存储结点或删除一个存储结点时,数据迁移量太大,代价太高。

       所以,一致性Hash算法将数据和存储节点映射到同个Hash空间,如转载的上篇文章中图所示,数据存储到其顺时针方向的第1个物理存储节点,一致性hash算法能很好地控制存储结点加入或离开导致的数据迁移量。

1.2  虚拟节点

上面的一致性hash算法存在什么样的问题呢,其实图已经比较清晰的了,如图中N0存储结点坏掉,会导致原来在N0上的数据到迁移到N1上,这样N1实际存储的数据就多了很多。

       一致性hash存在的问题就是存储节点不能将hash空间划分均匀,实际上是数据不能均匀分布在存储节点上,节点负载不均衡的。那如何解决这个问题呢?于是有了虚拟节点,那它是如何做到的呢。

       虚拟节点是相对物理存储节点而言,虽然虚拟节点是为了均匀分散hash存储空间,但虚拟节点负责存储的数据实际上还会存储在虚拟节点对应的物理存储节点上,略微有些绕。

       看图说话,数据存储到其顺时针方向的第1个节点(虚拟或物理节点)。虚拟节点按照物理节点来处理。Ni_0代表该虚拟节点对应于物理节点i的第0个虚拟节点。增加虚拟节点后,物理节点N0负责[N1_0, N0]和[N0, N0_0]两个分区,为什么呢?首先[N1_0, N0]之间的数据,物理节点N0负责,其次[N0, N0_0]之间的数据由N0_0负责,N0_0是虚拟节点,对应的物理存储节点是N0,所以实际上还是物理节点N0负责的。

       实际应用中,又可以根据物理节点的磁盘容量的大小来确定其对应的虚拟节点的数量,虚拟节点数目越多,节点负责的数据区间也越大。这里先假定认为(我还没有找到证据),当物理存储结点挂掉,其对应的虚拟节点不会删除,会重新映射到一个新物理存储节点。

1.3  分离分区和分区位置

上面的算法还存在什么问题呢?对于新添加的数据,这样是可以的,当物理存储节点跪了,对于已经写入磁盘的数据需要重新计算hash值确定是否需要迁移到其他的节点。因为需要遍历磁盘中的所有数据,这个计算过程非常耗时。

       上面的情况是,划分分区是由虚拟节点分的,实际上数据的存储位置也是和虚拟节点相关的。数据的实际存储位置称为分区位置。

       在Dynamo的论文中提出了分离分区和分区位置的方法来解决这个问题。该方法将Hash空间划分成固定的若干个分区,虚拟节点不再用于划分分区而用来确定分区的存储位置。采用固定分区的方式,虚拟节点是用来确定分区位置。分区固定,由于分区固定,因此迁移数据时可以很容易知道哪些数据需要迁移哪些数据不需要迁移。

       看图说话,一般为了分区分布的更均匀,说白了就是数据分布的更均匀,分区数目和虚拟节点的数目相同,每个虚拟节点负责一个分区,每个分区大小相同。

       我的理解就是,采用固定分区,分区数目取某一固定值,这个值怎么取,取几,取定后还能不能修改,都是不知道。分区数目固定,虚拟节点数目取相等的值,一个虚拟节点负责一个分区,也就是一个分区上的数据都存在这个虚拟节点上,每个分区大小相同,保证数据分布均匀。有虚拟节点到物理存储节点的映射关系。当某个物理节点跪掉,找到在其上的虚拟节点,直接确定不需要计算,则该分区负责的数据迁移到顺时针方向上的第一虚拟机节点。

   即使物理存储节点跪掉,对应的虚拟存储节点是不是不会跪掉,只需要修改下映射关系?先疑问着?答案有了,虚拟节点不会跪掉,虚拟节点负责的数据迁移到顺时针方向的第一个物理存储节点,猜的。

2.  Ceph

主要讨论了一部分,我对ceph的认识还停留在很简单层面的。Ceph优势,支持高扩展到PB级,高可靠因为有CRUSH算法。

2.1 CRUSH算法的引言

         讲了几次了,这是我印象最为深刻的部分,file、objects、PGs、OSDs的对应关系图,图自己寻找吧。图说明的问题就是,1个file分为n个objects,n个objects可以对应1个PG,1个PG对应k个OSD,k是副本的个数,OSD和PG的关系是,1个OSD上可以有多个PG,PG是virtual node,仅仅是简单叙述了下个数的对应关系,还是看看图会比较清晰的了。

       分布数据过程:(1)(ino, ono)-> oid:根据inode和object number计算得出全局唯一的oid;(2)hash( OID ) & mask: 根据oid计算hash值,与一些修订值得到pgid。

2.2  CRUSH算法

CRUSH算法是根据pgid计算出对应的一组OSD。整个过程有两次映射,第一次是从oid到PGID的映射,第二次是从PGID到一组OSD的映射。其中从oid到PGID的映射采用的方法类似于,该篇文章中最早提到hash算法,因为PG是抽象的存储节点,不会随着物理节点的增加或减少而变化,oid到pgid的映射关系是稳定的。

         为什么需要添加一个层次PG,PG还是虚拟的?这个是之前讨论过的问题。先分析PG起的什么作用。PG是抽象的存储节点,PG的数目是固定的,PG起两个作用:(1)PG起到划分分区的作用,和上面描述的一致性hash算法最后一种固定分区道理是相同的,PG是划分固定分区,PG将数据(这个数据指的就是object)均匀分布在每个PG上,每个PG管理的数据分区相同。(2)充当Dynamo中token的作用,即决定分区的位置,根据PG(对应虚拟节点)就能得到数据具体的物理存储节点。

         静下心来,好好想想,其实和最后一个一致性hash算法中固定分区、分离分区和分区位置的作用完全相同,PG干的就是这个事。PG做固定分区使用,再做分区位置使用。

         懂了PG。CRUSH算法采用了类似于一致性hash的算法,PG的作用类似于固定分区、分离分区和分区位置的作用。

3.  参考文章

[1] http://www.cnblogs.com/shanno/p/3958298.html?utm_source=tuicool

[2] http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf 看看!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值