一种分布式块存储系统的数据分布算法的制作方法

文档序号:18008673发布日期:2019-06-25 23:42阅读:215来源:国知局
一种分布式块存储系统的数据分布算法的制作方法

本发明涉及计算机技术领域,尤其涉及一种分布式块存储系统的数据分布算法。



背景技术:

分布式存储系统通常采用一致性哈希算法处理数据块分布问题。一致性哈希算法具备强一致性的特点,使得在发生网络拓扑变更时,只会迁移相对少量的部分数据;并且,无论网络拓扑形成的过程如何,只要静态拓扑结构一致,则数据块的分布特性也完全一致。

目前常用的一致性哈希算法在数据分布平衡性上存在明显的缺陷,即使通过引入“虚拟节点”的方法,缓解这种平衡性缺陷,但仍然无法避免,在极端情况下,数据倾斜度可能超过50%。而数据分布不平衡首先会带来存储成本的上升。一个分布式存储集群的容量上限往往受制于集群中最先写满的硬盘,即集群中某块硬盘一旦写满,整个集群的容量也就到达了上限,而无论集群中其他硬盘还有多少可用容量也都没有办法加以利用了。其次,数据分布不均衡也给存储集群运维带来困难。当集群中某块硬盘由于某种原因(如损坏)而掉线时,分布式存储通常都会将集群中的数据进行重新分布(recovery),从而保证掉线硬盘中的数据在其他的硬盘上重新恢复。而数据重新分布的过程同样会应用一致性哈希算法,导致数据的重新分布实际上是不可控的,这可能会导致某些硬盘的使用容量急剧上升,甚至写满从而导致集群不可用。



技术实现要素:

有鉴于现有技术的上述缺陷,本发明所要解决的技术问题是提供一种分布式块存储系统的数据分布算法,通过引入节点数上限和增加计算哈希映射关系的复杂度,换取数据分布的均衡性;通过引入分布式并行计算,保证哈希映射关系计算效率。

为实现上述目的,本发明提供了一种分布式块存储系统的数据分布算法,包括以下步骤:

步骤1、数据分布算法给分布式存储集群中的节点数设置一个上限n,集群中的任意节点加入集群时,系统给它分配一个全局唯一的编号(0~n-1),以后这个节点无论离线上线多少次,编号仍然保留;设上述存储集群节点编号的全集为sn={0,1,2,…n-1},假设实际的分布式存储集群节点数为m,则可知m≤n,设实际集群的在线节点编号为集合sm,则可知即sm是{0,1,2,…m}的子集,可知

步骤2、分布式存储中最小的数据单元为一个数据对象(dataobject),大小一致(如512k字节),生成一个数据对象(如上层应用写入新的数据),系统都会分配一个唯一的oid给该对象,每个数据对象都在存储集群中保存为三个副本,并且分散到不同的节点上以提高可靠性;

步骤3、引入一个hash函数,该函数将上述的一个oid映射成一个唯一的整数,且该整数在一个固定的区间内,即最大值为hmax,最小值为0,即

h=hash(oid),h为整数,且0≤h≤hmax(公式1)

该哈希函数与一般的哈希函数特性相同,即满足输入相同的oid,则返回相同的哈希值;同时对所有的oid的集合,计算得到的哈希值h应尽可能的随机的平均分布到区间[0,hmax]中;

步骤4、引入一个伪随机数函数rand(),这个函数输入一个自然数作为种子,返回一个取值范围为[0,n-1]的非负整数和一个新种子,其中n为上述第一条中的存储集群的节点数上限,即:

(rn,seedn)=rand(seedn-1),其中rn,seedn∈自然数,0≤rn≤n-1(公式2)

该函数还应该满足以下两点:

(1)设(r1,y1)=rand(x1),(r2,y2)=rand(x2),如果x1=x2则r1=r2,y1=y2;

(2)如果公式2中的n取得足够大,则通过迭代调用公式2而返回的序列(r0,r1,r2,....rn)中一定能找到整数序列(0~n-1)中的所有数字,换句话说,设序列(r0,r1,r2,....rn)包含的整数为整数集合s1,则一定存在一个正整数x,当n>x时,s1=sn,其中sn为第一条中的存储集群可能的节点编号的全集;通常的线性同余算法即可实现上面第(1)点,而对取得的随机数对n取模即可实现第(2)点;

步骤5、将该伪随机数函数应用到分布式集群中:一个数据对象的oid的哈希值(即上述步骤3中的公式1)作为初始种子输入,然后不断迭代上述第4条的公式2,得到一个随机数的序列rn=(r0,r1,r2,…rn),由步骤4可知,只要n足够大,该序列包含所有可能的节点号(即0~n-1),遍历该随机数序列rn,如果ri(0≤i≤n)不属于在线节点,继续读取下一个值,如果属于在线节点,则保留该值,直到取得三个不同的在线节点id,即

ri,rj,rk,其中0≤i,j,k≤n,而sm为步骤1中在线节点的集合。

上述的一种分布式块存储系统的数据分布算法,所述数据分布算法建立了从数据块的oid到实际在线的存储节点之间的映射,具体过程是从oid计算哈希值h,然后从h计算随机数列rn,并从中得到前三个在线的存储节点ri,rj,rk的过程,为了计算加速,程序需要对这个映射表进行缓存,该映射表函数可以表示为:

(ri,rj,rk)=map(h)公式3

上述的一种分布式块存储系统的数据分布算法,所述步骤1中的n是整个数据集群中所有虚节点的数量上限,其余的算法都是相同的,假设虚节点id表示为vnodeid,数据集群的虚节点到实际节点的映射关系为:

nodeid=vnode_map(vnodeid)公式4

当通过公式3计算出ri,rj,rk三个虚节点vnodeid之后,即可通过公式4计算出相应的节点id。

上述的一种分布式块存储系统的数据分布算法,所述数据分布算法采用并行计算的方法,具体为:

1)将哈希映射表切割成k个分片(slices),每个slice包含hmax/k个哈希值;

2)当前所有在线数据节点平均分配slices,避免某一个节点负担过重,分配算法如下:

按照数据节点加入集群的顺序,将片数1分配到第一个加入集群的数据节点(节点号按照加入集群的先后顺序递增),片数2分配到第二个加入集群的数据节点,依次类推,最多分配到第p个数据节点时,再从第一个数据节点重新分配下一个片数,最多参与计算的节点个数p是可配的,比如设成512;

3)每个数据节点使用多线程并发计算,为了避免线程数过多,可以设置一个线程数的上限,如32个;

4)每个线程按照前面的数据分布算法计算自己的分片;

5)各个节点在计算任务开始时,会按照步骤3描述的算法集中的先计算分配给自己的slice,并且基本上都会差不多在相同的时间完成本地计算;然后,在执行从远端节点读取slice的命令时,基本上远端节点均已完成slice计算,这样就减少了重复计算slice的几率;

6)各个计算线程将结果保存至本地一个临时哈希表文件,并将其他节点上的哈希表获取到本地,合并成一个完整的hashmap;

7)未参与运算的节点,则从参与运算的节点上获取完整的hashmap文件。

本发明的有益效果是:

本发明通过引入节点数上限和增加计算哈希映射关系的复杂度,换取数据分布的均衡性;通过引入分布式并行计算,保证哈希映射关系计算效率。

以下将结合附图对本发明的构思、具体结构及产生的技术效果作进一步说明,以充分地了解本发明的目的、特征和效果。

附图说明

图1是本发明的存储系统整体框架图。

图2是本发明的分布式并行计算哈希表的流程图。

图3是本发明的分布式计算哈希表流程图。

具体实施方式

本发明提供了一种分布式块存储系统的数据分布算法,包括:

一.数据分布算法

1.分布式存储集群中的节点数设置一个上限n,集群中的任意节点加入集群时,系统给它分配一个全局唯一的编号(0~n-1),以后这个节点无论离线上线多少次,编号仍然保留。设上述存储集群节点编号的全集为sn={0,1,2,…n-1}。假设实际的分布式存储集群节点数为m,则可知m≤n。设实际集群的在线节点编号为集合sm,则可知即sm是{0,1,2,…m}的子集(因为有可能有节点掉线而导致节点i不在线,0≤i≤m)。可知分布式存储集群需要知道自己集群中所有实际在线节点的编号。

2.分布式存储中最小的数据单元为一个数据对象(dataobject),大小一致(如512k字节)。每一个数据对象在分布式存储系统中都有唯一的一个标识(oid)。即每新生成一个数据对象(如上层应用写入新的数据),系统都会分配一个唯一的oid给该对象。每个数据对象都在存储集群中保存为三个副本,并且分散到不同的节点上以提高可靠性。

3.引入一个hash函数,该函数将上述的一个oid映射成一个唯一的整数,且该整数在一个固定的区间内,即最大值为hmax,最小值为0。即

h=hash(oid),h为整数,且0≤h≤hmax(公式1)

该哈希函数与一般的哈希函数特性相同,即满足输入相同的oid,则返回相同的哈希值;同时对所有的oid的集合,计算得到的哈希值h应尽可能的随机的平均分布到区间[0,hmax]中。这样的哈希函数有很多可参考的实现。

4.引入一个伪随机数函数rand(),这个函数输入一个自然数作为种子,返回一个取值范围为[0,n-1]的非负整数和一个新种子,其中n为上述第一条中的存储集群的节点数上限,即:

(rn,seedn)=rand(seedn-1),其中rn,seedn∈自然数,0≤rn≤n-1(公式2)

该函数还应该满足以下两点:

(1)设(r1,y1)=rand(x1),(r2,y2)=rand(x2),如果x1=x2则r1=r2,y1=y2。

(2)如果公式2中的n取得足够大,则通过迭代调用公式2而返回的序列(r0r1r2,....rn)中一定能找到整数序列(0~n-1)中的所有数字。换句话说,设序列(r0,r1,r2,....rn)包含的整数为整数集合s1,则一定存在一个正整数x,当n>x时,s1=sn,其中sn为第一条中的存储集群可能的节点编号的全集。

该伪随机函数是容易实现的,通常的线性同余算法即可实现上面第(1)点,而对取得的随机数对n取模即可实现第(2)点。

5.将该伪随机数函数应用到分布式集群中:一个数据对象的oid的哈希值(即上述第3条中的公式1)作为初始种子输入,即上面第3条中的seed0,然后不断迭代上述第4条的公式2,得到一个随机数的序列rn=(r0,r1,r2,....rn)由第4条可知,只要n足够大,该序列包含所有可能的节点号(即0~n-1)。遍历该随机数序列rn,如果ri(0≤i≤n)不属于在线节点,继续读取下一个值,如果属于在线节点,则保留该值,直到取得三个不同的在线节点id,即

ri,rj,rk,其中0≤i,j,k≤n,而sm为第1条中在线节点的集合。

6.如上所述,对同一个哈希值,输出的节点编号序列是固定的,只要静态网络拓扑保持不变,数据块在节点上的分布也将完全一致,这就保证了算法的强一致性。

7.当分布式存储集群发生拓扑变更时(节点离线),部分数据对象会发生副本损失,但是根据上述伪随机函数的特性,其未损失的部分副本位置不变,当然也不会发生迁移,这就保证了该数据对象仍然可读。

8.在分布均衡性方面,无论拓扑如何变化,该算法都能保证不会出现明显的倾斜,经实验验证,在6000个数据节点的场景下,节点间哈希倾斜率通常在5%以内,极少情况下(在测试中不超过5%)可达10%左右。

上述算法建立了从数据块的oid到实际在线的存储节点之间的映射。具体过程是从oid计算哈希值h,然后从h计算随机数列rn,并从中得到前三个在线的存储节点ri,rj,rk的过程。为了计算加速,程序需要对这个映射表进行缓存。该映射表函数可以表示为:

(ri,rj,rk)=map(h)公式3

二.数据分布式算法的一个变化

为了使数据分布更加均匀,同时引入更灵活的机制来衡量存储集群中不同节点的权重,在实际的工程中还往往引入虚节点(virtualnode)的概念。一个实际的物理节点包括多个虚节点,实际往往是2n个节点,如32,64等。例如有个节点,一个节点a量是2t,另个节点b量是4t,那么可以设置a节点有32个虚节点,b节点有64个虚节点,这样数据块落到b节点的概率就是a节点的2倍,从而达到数据平衡的效果。假设虚节点id表示为vnodeid,则上述第1条中的n就是整个数据集群中所有虚节点的数量上限,其余的算法都是相同的。数据集群需要知道虚节点到实际节点的映射关系:

nodeid=vnode_map(vnodeid)公式4

当通过公式3计算出ri,rj,rk三个虚节点vnodeid之后,即可通过公式4计算出相应的节点id。

三.分布式并行计算

该算法的计算复杂度相比常用的一致性哈希算法要高,因而需要预先将哈希映射关系计算出来,后续使用时,直接查询映射关系表,避免每次哈希时进行计算。上述公式3中的h为公式1中的哈希函数返回值,而该返回值范围是有限的,即0≤h≤hmax。因此上述公式3的映射关系表大小固定。实际工程中,因为hash算法的不同该映射关系表的大小也不同,通常应该在几十兆至上百兆字节,是可以被计算出来并缓存起来的。

为了保证计算效率,我们采用并行计算的方法。

1.将哈希映射表切割成k个分片(slices),每个slice包含hmax/k个哈希值;

2.当前所有在线数据节点平均分配slices,避免某一个节点负担过重,分配算法如下:

按照数据节点加入集群的顺序,将片数1分配到第一个加入集群的数据节点(节点号按照加入集群的先后顺序递增),片数2分配到第二个加入集群的数据节点,依次类推,最多分配到第p个数据节点时,再从第一个数据节点重新分配下一个片数。最多参与计算的节点个数p是可配的,比如设成512。

因为存储集群中每个节点都保存有整个集群的拓扑信息,即在线节点集合sm,所以每个节点不需要额外的通信和协商就可以通过计算得知自己是否应该参与计算,以及需要计算哪些分片。同时根据前面的公式2和公式3可知,计算过程不需要依赖于其他节点,只需要知道sm的信息即可。

该分配算法特点总结如下:

a)每个节点只需要sm的信息即可知道自己是否需要参与计算,以及自己负责的分片。

b)每个节点只需要sm的信息即可知道需要其余所有节点是否参与计算,以及负责的分片。

c)各个参与计算的节点分配到的计算任务最多不会超过一个slice,这样就保证了参与计算的各个节点完成任务的时间相差不会太多(前提是各节点计算能力相同或相近)。

举例说明,假设集群中只有三个节点,分片个数k=12,则第一个节点计算第0、3、6、9分片,第二个节点计算1、4、7、10分片,第三个节点计算第2、5、8、11分片。

3.每个数据节点使用多线程并发计算,为了避免线程数过多,可以设置一个线程数的上限,如32个;

4.每个线程按照前面的数据分布算法计算自己的分片。

5.各个节点在计算任务开始时,会按照上面第3点描述的算法集中的先计算分配给自己的slice,并且基本上都会差不多在相同的时间完成本地计算;然后,在执行从远端节点读取slice的命令时,基本上远端节点均已完成slice计算,这样就减少了重复计算slice的几率;

6.各个计算线程将结果保存至本地一个临时哈希表文件,并将其他节点上的哈希表获取到本地,合并成一个完整的hashmap;

7.未参与运算的节点,则从参与运算的节点上获取完整的hashmap文件。

本发明所属的可能的分布式存储系统整体系统架构图如附图1所示。其中存储网关负责接收存储客户端的指令,下发存储指令到存储进程,并返回存储指令的结果给存储客户端。而存储进程负责将实际的数据读写到实际的存储介质之中,如硬盘等。例如:

一个写操作,存储客户端将写操作的指令,包括要写的数据内容发给一个存储网关,存储网关将利用本发明描述的算法将要写入的数据分发到选定的三个存储节点,写成功后将结果返回,比如是否写成功,以及写入的数据对象id等。

如果是一个读操作,存储客户端告知要读的内容所处的数据对象id(即oid),存储网关利用本发明所描述的算法,通过读取的数据对象id计算出该数据对象具体所在的三个存储节点,并选择其中一个可用的节点(通常是第一个节点),然后向该节点发送读请求,并将成功读取的数据返回给存储客户端。

存储网关与存储进程相互独立,他们可以在同一台机器上,也可以在不同的机器上。存储客户端与存储网关,以及存储网关和存储进程之间的通信协议可以是任何可行的协议,不在本发明范围之内。存储客户端如何确定要读写的数据对象也不在本发明范围之内。整个存储集群通过某种机制,如p2p机制,或者类似zookeeper等集中调度软件来协调存储集群成员,如发现集群成员的掉线,或新成员的加入等,而该机制不在本发明范围之内。

本发明描述的数据分布算法实现于各个存储网关之中。在实现上可以分成以下几部分。

1)在集群初始阶段根据上面公式2计算哈希表,并且把该表缓存到系统中。

2)在系统运行阶段根据客户端请求的数据oid和公式1计算哈希值,并利用上一步中计算得到的哈希表和公式3计算该数据对象所处的存储节点。

3)当集群发生变化时,存储集群拓扑发生变化,即有新加入的节点或者掉线的节点,这时应该重新根据公式2计算哈希表。

当重新计算哈希表后,有些数据对象需要重新移动到新的存储节点。如何移动这些数据对象不在本发明范围之内。

对于上面第1)部分,可参考下面的流程图,该流程图描述了如何计算全部哈希表。说明如下:

a)系统初始化完毕,所有节点加入系统,每个节点都已经获取整个集群的拓扑sm。

b)遍历每一个从公式2中可能的哈希值,即0~hmax。对于每个哈希值,作为初始种子带入公式2。

迭代调用公式2,对于每一次返回的随机数判断是否属于在线节点集合sm,如果属于sm,则存入哈希表,直到对当前哈希值已经得到了三个在线节点。

以上详细描述了本发明的较佳具体实施例。应当理解,本领域的普通技术人员无需创造性劳动就可以根据本发明的构思做出诸多修改和变化。因此,凡本技术领域中技术人员依本发明的构思在现有技术的基础上通过逻辑分析、推理或者有限的实验可以得到的技术方案,皆应在由权利要求书所确定的保护范围内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1