Ring是swfit中最重要的组件,用于记录存储对象与物理位置之间的映射关系,当用户需要对Account、Container、Object操作时,就需要查询对应的Ring文件(Account、Container、Object都有自己对应的Ring),Ring 使用Region(最近几个版本中新加入的)、Zone、Device、Partition和Replica来维护这些信息,对于每一个对象,根据你在部署swift设置的Replica数量,集群中会存有Replica个对象。部署完成后,相应的Ring文件也创建,如我上篇博客中部署示例,在/etc/swift中会存有Ring文件。
Swift利用一致性Hash算法构建了一个冗余扩展的分布式对象存储集群、Swift采用一致性哈希的主要目的是在改变集群的device数量时,能够尽可能少地改变已存在Key和device的映射关系。本文将对一致性Hash算法进行一些理解性的介绍,关于一致性Hash算法其他参考资料做具体的理解。swift中一致性hash算法的具体代码实现,我将在下边几篇博客中具体介绍。
图1 环形Ring
如图所示的,hash算法将value映射成一个0—2**32-1的数值空间。
假设有四个对象、通过hash函数计算每一个对象对应的hash值在环上的分布如下。swift中利用了MD5哈希算法,根据对象的名字进行hash的:
hash(object1)=key1;
...........
hash(object4)=key4
图2 object的key值映射到Ring
对应存储设备,利用同样的Hash算法,将value映射到环上,假如有三个设备device1,device2,device3,他们对应的hash值为dev1,dev2,dev3,其在Ring上的分布如下图所示。
图3 设备映射到Ring
现在设备和对象通过hash算法都映射到了Ring上,那么如何将对象映射到将要存储的设备上呐,在这个环,每一个对象从自己在环上的位置开始,按顺时针方向移动,直到遇到一个设备,则把对象存入到此设备上,如上图所示,则key1会映射到dev2,key4映射到dev3,key3,key2映射到dev1。如果增加一个设备device4,若其hash值为dev5,其在Ring上的映射为
图4 新增设备后的Ring
对于新增的设备device4,环中需要变动的对象只有key3所对应的对象,它在按顺时针找设备时找到的是device4而不是device1,其他的数据存储不变,这样减少了数据的迁移。
平衡性是hash算法的一个重要指标,平衡性是指对于存储的所有对象,尽可能均匀的分不到所有的设备上去。如上图所示,若是hash算法所算出的对象hash值大多数落在顺时针方向的key4到key2之间时,还是按如上方法对象映射设备,device2就得到很少的对象存储,以至于其他三个设备承受了比较大的压力。显然这样设计是不符合实际需求的。引入虚拟节点能很好的解决此问题。
虚拟节点实际上是实际节点在空间中的复制品,一个实际的节点对应若干个虚拟的节点,加入虚拟节点后,对象的存储从对象—设备的映射转换为对象——虚拟节点——设备的映射,虚拟节点在空间中按hash值排列。假如虚拟节点为20个,他们均匀的分布在Ring中,每一个设备对一个的虚拟节点为5个,对象映射设备时变为如图所示的过程:
图5 对象—虚拟节点—设备映射过程
在Ring每一个设备引入了weight概念,weight 的作用就是,假如一个集群中有的设备容量为1T,有的为2T、3T,对于不共同的设备,在存储数据时,我们肯定希望容量的更大的设备有更多的被选择的机会,存储更多的对象,通过设置weight,存储容量多的设备有更大的权重,它也就有了更大的part_wants,那么就会有更多的虚拟节点和它映射,有更多的虚拟节点映射后,对象就有更大的可能落在它所对应的虚拟节点上,这样就会有更多的机会得到对象。
在部署swift 时可以设定数据的 最小迁移时间如我上篇博客swift部署中指示的为1个小时
swift-ring-builder object.builder create 18 3 1
上两节介绍了Ring的基本原理以及一致性hash算法的原理,现在讲解Ring是如何使用一致性hash算法的。在Ring 中有一个replica2part2dev(备份到分区到设备的映射),replica2part2dev是含有replica(replica为正整数时,)个子list的list,,每一个子list含有2**power个元素。当replica为>1的float值时会有int[replica]+1个子list,其中最后一个list长度为(replica-int[replica])*2**power。比如在2.2.4中部署时指示的power为18 ,replica为3,而每一个元素中存放的是设备的id。如下所示power为8,replica为3,3个设备且在三个zone中,经过reassign_parts后得到的replica2part2dev,0,1,2即为设备的ID。
[ [2, 2, 0, 0, 2, 0, 0, 2, 1, 0, 0, 0, 2, 0, 1, 2, 2, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1, 2, 0, 2, 2, 0, 1, 0, 2, 1, 1, 0, 2, 0, 2, 1, 0, 1, 1, 0, 1, 1, 0, 2, 0, 1, 1, 1, 2, 2, 0, 2, 1, 1, 2, 2, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0,
1, 1, 1, 2, 0, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 0, 2, 1, 2, 0, 1, 1, 2, 2, 0, 2, 1, 2, 2, 0, 1, 1, 0, 0, 2, 1, 0, 2, 0, 2, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 2, 2, 1, 1, 0, 0, 1, 1, 0, 1, 2, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 2, 2, 2, 0, 0, 1, 0, 0,
0, 0, 2, 2, 2, 2, 0, 1, 0, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 0, 1, 0, 2, 2, 1, 2, 1, 2, 0, 2, 2, 0, 2, 0, 1, 0, 1, 2, 1, 1, 2, 2, 1, 0, 2, 1, 2, 2, 0, 0, 0, 1, 2, 2, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 0, 1, 1, 0, 1, 2, 2, 2, 0, 2, 2, 0, 1, 2, 1, 2, 0, 0, 2,
0, 0, 1, 1, 0, 2, 2, 2, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 1, 2, 1, 1, 0, 1, 1, 2, 0, 2, 1, 2, 0, 1, 2, 0, 0, 0, 1, 0, 1, 1, 2, 2, 1, 0, 2, 2, 0, 2, 1, 2, 1, 0, 0, 1, 2, 2, 2, 0, 2, 2, 0, 0, 1, 0, 2, 1, 2, 2, 1, 1, 0, 0, 0, 2, 1, 0, 2, 2, 2, 1, 1, 1, 0, 0, 2, 0, 2, 2, 2, 0, 2, 0, 2,
2, 0, 0, 0, 0, 2, 2, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 2, 1, 1, 1, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1, 1, 0, 1, 0, 2, 0, 0, 2, 2, 1, 0, 0, 2, 1, 1, 2, 0, 2, 0, 1, 2, 2, 1, 2, 1, 0, 1, 1, 1, 2, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 0, 0, 1, 2, 0, 1, 2, 1,
1, 2, 0, 2, 0, 1, 1, 1, 2, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 1, 1, 0, 2, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 2, 0, 0, 0, 2, 0, 1, 2, 2, 2, 2, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1, 0, 0, 2, 1, 0, 2, 2, 0, 2, 2, 1, 1, 1, 1, 2],
[0, 0, 2, 2, 0, 2, 2, 1, 0, 1, 2, 1, 0, 2, 2, 0, 0, 1, 2, 1, 2, 1, 2, 0, 0, 2, 2, 1, 2, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 1, 1, 1, 0, 2, 2, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 0, 2, 1, 0, 0, 1, 0, 2, 2, 2, 2, 0, 1, 1, 1, 1, 2, 1, 1, 1, 0,
2, 2, 2, 1, 0, 0, 0, 1, 2, 1, 2, 0, 2, 0, 1, 2, 0, 0, 0, 2, 1, 2, 1, 1, 2, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 2, 2, 2, 1, 1, 2, 2, 0, 1, 0, 1, 2, 0, 2, 2, 0, 2, 1, 2, 0, 1, 1, 2, 1, 2, 2, 0, 0, 0, 1, 1, 0, 0, 2, 2, 0, 2, 2, 1, 1, 0, 1, 1, 0, 1, 2, 2, 0, 0, 0,
0, 2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 0, 1, 2, 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 2, 2, 2, 0, 1, 0, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 2, 0, 0, 2, 1, 1, 2, 1, 1, 1, 2, 0, 1, 0, 0, 0, 2, 0]]
在得到replica2part2dev后,当对象需要存放时,首先 根据对象的名字account/container/object,计算出其对应的hash值,取hash值的前4个字节(32位),将其右移32-power位,得到值即为partion的值,从partion中取出replica个对应设备的id,根据设备的id得到设备的其他属性返回,设备的其他属性中包含了设备的ip地址,port等信息,通过http请求,和三个设备建立链接,因为三个设备中运行了object-server,他们接收这些请求,将数据存入到设备中。 如图所示环的运行机制
图6 环的运行机制
1、http://www.ibm.com/developerworks/cn/cloud/library/1310_zhanghua_openstackswift/
2、http://blog.csdn.net/sparkliang/article/details/5279393?reload
OpenStack_Swift源码分析——Ring基本原理及一致性Hash算法,布布扣,bubuko.com
OpenStack_Swift源码分析——Ring基本原理及一致性Hash算法
原文地址:http://blog.csdn.net/xianghonglee/article/details/25718099