分布式理论 - 数据分布的方式

数据分布方式 

        所谓分布式系统顾名思义就是利用多台计算机协同解决单台计算机所不能解决的计算、存储等问题。单机系统与分布式系统的最大的区别在于问题的规模,即计算、存储的数据量的区别。将一个单机问题使用分布式解决,首先要解决的就是如何将问题拆解为可以使用多机分布式解决,使得分布式系统中的每台机器负责原问题的一个子集。由于无论是计算还是存储,其问题输入对象都是数据,所以如何拆解分布式系统的输入数据成为分布式系统的基本问题,本文称这样的数据拆解为数据分布方式,介绍几种常见的数据分布方式,最后对这几种方式加以对比讨论。 

  • 哈希方式 

        哈希方式是最常见的数据分布方式,其方法是按照数据的某一特征计算哈希值,并将哈希值与机器中的机器建立映射关系,从而将不同哈希值的数据分布到不同的机器上。所谓数据特征可以是key-value 系统中的 key,也可以是其他与应用业务逻辑相关的值。例如,一种常见的哈希方式是按数据属于的用户id计算哈希值,集群中的服务器按0到机器数减1编号,哈希值除以服务器的个数,结果的余数作为处理该数据的服务器编号。工程中,往往需要考虑服务器的副本冗余,将每数台服务器组成一组,用哈希值除以总的组数,其余数为服务器组的编号。下图给出了哈希方式分数据的一个例子,将数据按哈希值分配到 4 个节点上。 


            可以将哈希方式想象为一个大的哈希表,每台(组)机器就是一个哈希表中的桶,数据根据哈希值被分布到各个桶上面。 只要哈希函数的散列特性较好,哈希方式可以较为均匀的将数据分布到集群中去。哈希方式需要记录的元信息也非常简单,任何时候,任何节点只需要知道哈希函数的计算方式及模的服务器总数就可以计算出处理具体数据的机器是哪台。 
           哈希分布数据的缺点同样明显,突出表现为可扩展性不高,一旦集群规模需要扩展,则几乎所有的数据需要被迁移并重新分布。工程中,扩展哈希分布数据的系统时,往往使得集群规模成倍扩展,按照数据重新计算哈希,这样原本一台机器上的数据只需迁移一半到另一台对应的机器上即可完成扩展。 
           针对哈希方式扩展性差的问题,一种思路是不再简单的将哈希值与机器做除法取模映射,而是将对应关系作为元数据由专门的元数据服务器管理。访问数据时,首先计算哈希值并查询元数据服务器,获得该哈希值对应的机器。同时,哈希值取模个数往往大于机器个数,这样同一台机器上需要负责多个哈希取模的余数。在集群扩容时,将部分余数分配到新加入的机器并迁移对应的数据到新机器上,从而使得扩容不再依赖于机器数量的成本增长。
           哈希分布数据的另一个缺点是,一旦某数据特征值的数据严重不均,容易出现“数据倾斜”(dataskew)问题。例如,某系统中以用户 id 做哈希分数据,当某个用户 id 的数据量异常庞大时,该用户的数据始终由某一台服务器处理,假如该用户的数据量超过了单台服务器处理能力的上限,则该用户的数据不能被处理。更为严重的是,无论如何扩展集群规模,该用户的数据始终只能由某一台服务器处理,都无法解决这个问题。下图图给出了一个数据倾斜的例子,当使用用户 id 分数据,且用户 1 的数据特别多时,该用户的数据全部堆积到节点 2 上。  

  
            在这种情况下只能重新选择需要哈希的数据特征,例如选择用户 id 与另一个数据维度的组合作为哈希函数的输入,如这样做,则需要完全重新分布数据,在工程实践中可操作性不高。另一种极端的思路是,使用数据的全部而不是某些维度的特征计算哈希,这样数据将被完全打散在集群中。然而实践中有时并不这样做,这是因为这样做使得每个数据之间的关联性完全消失,例如上述例子中一旦需要处理某种指定用户 id 的数据,则需要所有的机器参与计算,因为一个用户 id 的数据可能分布到任何一台机器上。如果系统处理的每条数据之间没有任何逻辑上的联系,例如一个给定关键词的查询系统,每个关键词之间并没有逻辑上的联系,则可以使用全部数据做哈希的方式解决数据倾斜问题。 

  • 按数据范围分布 

         按数据范围分布是另一个常见的数据分布式,将数据按特征值的值域范围划分为不同的区间,使得集群中每台(组)服务器处理不同区间的数据。 
例:已知某系统中用户 id 的值域范围是[1,100),集群有 3 台服务器,使用按数据范围划分数据的数据分布方式。将用户 id 的值域分为三个区间[1, 33),,[33, 90),[90, 100)分别由 3 台服务器负责处理。下图给出这个例子的示意图。 
 

 
          值得注意的是,每个数据区间的数据大小和区间大小是没有关系的。例如,上例中按用户 id 划分的三个区间,虽然从用户 id 的值域看来,不是等大小的,但三个区间中的数据量却有可能是差不多的。这是因为可能有的用户 id 的数据量大,有些用户id 数据量小。也有可能某些区间中实际存在的用户 id 多,有些区间中实际存在的用户 id 少。工程中,为了数据迁移等负载均衡操作的方便,往往利用动态划分区间的技术,使得每个区间中服务的数据量尽量的一样多。当某个区间的数据量较大时,通过将区间“分裂”的方式拆分为两个区间,使得每个数据区间中的数据量都尽量维持在一个较为固定的阈值之下。 
          与哈希分布数据的方式只需要记录哈希函数及分桶个数(机器数)不同,按数据范围分布数据需要记录所有的数据分布情况。一般的,往往需要使用专门的服务器在内存中维护数据分布信息,称这种数据的分布信息为一种元信息。甚至对于大规模的集群,由于元信息的规模非常庞大,单台计算机无法独立维护,需要使用多台机器作为元信息服务器。 
实际工程中,一般也不按照某一维度划分数据范围,而是使用全部数据划分范围,从而避免数据倾斜的问题。 
          哈希分布数据的方式使得系统中的数据类似一个哈希表。按范围分数据的方式则使得从全局看数据类似一个 B 树。每个具体的服务器都是 B 树的叶子节点,元数据服务器是 B 树的中间节点。 使用范围分布数据的方式的最大优点就是可以灵活的根据数据量的具体情况拆分原有数据区间,拆分后的数据区间可以迁移到其他机器,一旦需要集群完成负载均衡时,与哈希方式相比非常灵活。另外,当集群需要扩容时,可以随意添加机器,而不限为倍增的方式,只需将原机器上的部分数据分区迁移到新加入的机器上就可以完成集群扩容。 
          按范围分布数据方式的缺点是需要维护较为复杂的元信息。随着集群规模的增长,元数据服务器较为容易成为瓶颈,从而需要较为负责的多元数据服务器机制解决这个问题。 

  •  按数据量分布 

          另一类常用的数据分布方式则是按照数据量分布数据。与哈希方式和按数据范围方式不同,数据量分布数据与具体的数据特征无关,而是将数据视为一个顺序增长的文件,并将这个文件按照某一较为固定的大小划分为若干数据块(chunk),不同的数据块分布到不同的服务器上。与按数据范围分布数据的方式类似的是,按数据量分布数据也需要记录数据块的具体分布情况,并将该分布信息作为元数据使用元数据服务器管理。 
          由于与具体的数据内容无关,按数据量分布数据的方式一般没有数据倾斜的问题,数据总是被均匀切分并分布到集群中。当集群需要重新负载均衡时,只需通过迁移数据块即可完成。集群扩容也没有太大的限制,只需将部分数据库迁移到新加入的机器上即可以完成扩容。按数据量划分数据的缺点是需要管理较为复杂的元信息,与按范围分布数据的方式类似,当集群规模较大时,元信息的数据量也变得很大,高效的管理元信息成为新的课题。 

  • 一致性哈希 

         一致性哈希(consistent hashing)是另一个种在工程中使用较为广泛的数据分布方式。一致性哈希最初在 P2P 网络中作为分布式哈希表(DHT)的常用数据分布算法。

         一致性哈希的基本方式是使用一个哈希函数计算数据或数据特征的哈希值,令该哈希函数的输出值域为一个封闭的环,即哈希函数输出的最大值是最小值的前序。将节点随机分布到这个环上,每个节点负责处理从自己开始顺时针至下一个节点的全部哈希值域上的数据。 
例 :某一致性哈希函数的值域为[0, 10),系统有三个节点 A、B、C,这三个节点处于的一致性哈希的位置分别为 1,4,9,则节点 A 负责的值域范围为[1,4),节点 B 负责的范围为[4, 9),节点 C 负责的范围为[9, 10)和[0, 1)。若某数据的哈希值为 3,则该数据应由节点 A 负责处理。示意图:


          哈希分布数据的方式在集群扩容时非常复杂,往往需要倍增节点个数,与此相比,一致性哈希的优点在于可以任意动态添加、删除节点,每次添加、删除一个节点仅影响一致性哈希环上相邻的节点。 
          例 : 假设需要在上例中增加一个新节点 D,为 D 分配的哈希位置为 3,则首先将节点A 中[3, 4)的数据从节点 A 中拷贝到节点 D,然后加入节点 D 即可。 
          使用一致性哈希的方式需要将节点在一致性哈希环上的位置作为元信息加以管理,这点比直接使用哈希分布数据的方式要复杂。然而,节点的位置信息只于集群中的机器规模相关,其元信息的量通常比按数据范围分布数据和按数据量分布数据的元信息量要小很多。 
          上述最基本的一致性哈希算法有很明显的缺点,随机分布节点的方式使得很难均匀的分布哈希值域,尤其在动态增加节点后,即使原先的分布均匀也很难保证继续均匀,由此带来的另一个较为严重的缺点是,当一个节点异常时,该节点的压力全部转移到相邻的一个节点,当加入一个新节点时只能为一个相邻节点分摊压力。 
为此一种常见的改进算法是引入虚节点(virtual node)的概念,系统初始时就创建许多虚节点,虚节点的个数一般远大于未来集群中机器的个数,将虚节点均匀分布到一致性哈希值域环上,其功能与基本一致性哈希算法中的节点相同。为每个节点分配若干虚节点。操作数据时,首先通过数据的哈希值在环上找到对应的虚节点,进而查找元数据找到对应的真实节点。使用虚节点改进有多个优点。首先,一旦某个节点不可用,该节点将使得多个虚节点不可用,从而使得多个相邻的真实节点负载失效节点的压里。同理,一旦加入一个新节点,可以分配多个虚节点,从而使得新节点可以负载多个原有节点的压力,从全局看,较容易实现扩容时的负载均衡。 (A节点 对应 虚拟节点A1,A2, 依次......)

即一个实际节点负载多个虚拟节点达到hash的平衡性。

 

内容总结于分布式系统原理介绍书籍.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值