【深度】带你读懂一致性哈希算法

一、传统哈希算法

传统的哈希表通常使用下面的方法将key映射到数组的索引(index):

hash = hashFunc(key)
index = hash % arraySize

这种方法的不足之处是当arraySize发生改变后,所有的key都需要重新映射(remapped),因为索引的值是对arraySize求余运算获得的。

这种技术可以用于把应用程序的数据分散存储到多个数据库中,从而实现数据分区(data partition),只需要把key的哈希值跟数据库的个数进行求余运算,得到的结果就是存放这个key的数据库的序号,如下图所示:

如果一个新数据库被添加到集群中,或者一个现有的数据库被移除出集群(或者是数据库服务器宕机),那所有的key都需要被重新映射,跟上面所说的哈希表的情况一样。假如你所要处理的数据非常多,可以想象对所有的key进行重新映射将是一个非常耗时的工作。

二、一致性哈希算法

1 构造值域环
一致性哈希就是用于解决传统哈希算法问题的。首先,函数 f f f 的输出的值范围[x0,xn]两端连起来形成环,如下:

2 服务器节点映射
利用函数 f f f ,把每个节点(node,可以理解成数据库服务器,key就是服务器的ip地址)映射到环上的一个点(a point):

环上两个节点之间形成一个分区(a partition)。如果对任何一个key使用同样的函数 f f f,最终会得到这个key在环上的一个映射点(projection):

3 数据分区计算
根据上面的理论,现在的任务是要确定存放key的服务器——从key对应的环上的映射点开始,沿着环做顺时针移动,碰到的第一个服务器节点就是负责存放key的服务器。

注意 f ( " V e n u s " ) f("Venus") f("Venus") 映射的点位于最后一个节点之后,按照函数 f f f 环逻辑,最终找到的节点就是10.1.2.3(蓝色的节点)。

4 节点加入
节点加入并不需要所有key都重新映射。只有一部分key需要被重新映射到一个不同的节点上(粉色节点上加入,Mars数据将被映射到 10.7.5.1):

5 节点移除
当一个节点被从环上移除,也只会有一部分key需要被重新映射(蓝色节点移除,Venus数据被重新映射到粉色节点上):

上面所介绍的算法就是一致性哈希的本质。这个想法是由Karger等人在1997的一篇论文 [1] 。所有节点被映射到一个环上,从而形成分区,之后再把key同样映射到环上,再沿着顺时针方向找到离key的映射点最近的节点,这个节点就是负责存储key的服务器节点。

6 数据均匀分布问题

使用一致性哈希可以避免热点问题,只要函数 f f f返回的哈希值足够均匀。所以即使多个看起来很相似的key,它们在环上的映射点也会完全不同,并且相距甚远,最终它们会被存放到不同的节点上。另外一个好处是当有新节点加入或从环上移除时,需要移动的key很容易处理,只是紧紧相邻的节点才会受到影响,对其他的节点则毫发无损。

使用一致性哈希的系统还可以使用其他技术来减轻环结构的改变所带来的不利影响,比如多节点数据副本存储。

使用一致性哈希的系统通常使用一种哈希函数的输出范围来构建环结构,哈希函数可以是SHA-1或者SHA-2。SHA-1的输出范围是从0到2160, SHA-2的输出范围各不相同,SHA-256是0到2256,SHA-512是0到2512等等。使用这些函数中的任何一个都会把节点映射到环上的一个随机位置。这样的得到的分区很可能不同的大小,换句话说就是每个节点所负责的数据量各不相同。这一特点的用处不大,不过这些哈希函数的输出范围都是固定的,所以整个环可以被预先分割为几个大小相等的分区,然后每个节点可以占有其中的几个分区,从而保证每个节点所处理的数据量基本相同。

另一个重要技术是虚拟节点(virtual nodes)
上面的介绍的环的特点是环上的节点跟一个真实存在的物理节点进行一对一映射。这会引出一个问题,随机在环上放置节点可能会导致节点间的数据分布不均匀,如下图所示:

当节点被移除的时候,这个问题会变得更明显,此时所有由这个节点所处理的数据都要被转移到一个其他的节点上。为了防止一个节点的移除导致另一个节点负载过大,同时为了让key的分布更加均匀,系统可以为物理节点和环上的节点建立一个不同的映射。除了本身存在的一对一的映射,系统还可以创建一些虚拟节点,并在物理节点和虚拟节点之间创建一个M对N的映射(如下图,1:3映射)。

有了这些虚拟节点,每个物理节点将会负责环上的多个分区。当一个节点被移除,由这个节点处理的负载会被平均分配给环上剩余的其他节点。

类似地,当一个节点加入到环上,它会从环上其他的每个节点中接收数据量相同的部分数据。虚拟节点对于由资源各异的各种不同的节点组成的系统也会有帮助,这些资源包括CPU核心、RAM和磁盘空间等。对于这种节点各异的集群,虚拟节点的数量可以根据物理节点的特性来确定。

7 本质
一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题,目前在很多分布式系统中应用广泛,如:Amazon’s Dynamo 、Riak、Akka和 Chord等。

本文转自:一致性哈希算法,如有侵权,烦请联系删除!

引用
[1] D. Karger, E. Lehman, T. Leighton, R. Panigrahy, M. Levine, and D. Lewin, Consistent hashing and random trees: distributed caching protocols for relieving hot spots on the World Wide Web. New York, New York, USA: ACM, 1997, pp. 654–663.
[2] http://blog.carlosgaldino.com/consistent-hashing.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值