一致性哈希算法

一、传统算法的缺陷

对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。

求余算法: hash(Key)%N              [ N:服务器数量 ]

使用一般的取余算法,操作很简单,计算数据分布计算量非常简单。但是存在一个致命缺陷,如果增加一台服务器或者减少一台服务器,带来的结果可能如下:

  • 数据重排
  • 数据失效

那么有什么办法解决一般算法中节点失效引起的数据需要重排的问题呢?要解决这个问题,当然得二般的办法:


二、Consistent Hashing 一致性hash的原理

简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在key 映射关系,尽可能的满足单调性的要求。

1. 环形hash 空间

考虑通常的 hash 算法都是将 value 映射到一个 32 为的 key 值,也即是 0~2^32-1 次方的数值空间;我们可以将这个空间想象成一个首( 0 )尾( 2^32-1 )相接的圆环。数据和服务器都映射到这个圆环上。

一致性哈希算法_第1张图片

2.映射服务器节点到hash圆环

一致性哈希算法_第2张图片

3.映射数据对象到hash圆环

一致性哈希算法_第3张图片

Consistent hashing 的基本思想就是将对象和 服务器都映射到同一个 hash 数值空间中,并且使用相同的 hash算法。

4.将映射到圆环上的数据映射到服务器节点上去

一致性哈希算法_第4张图片

在这个环形空间中,沿着顺时针方向从数据的 key 值出发,直到遇见一个 服务器节点 ,那么就将该数据存储在这个 服务器节点,因为数据的key和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。这样就找到了数据和 服务器的映射方法了。


5.增删服务器节点对数据存储的影响

如果采用Hash(Object)%N的方式,当N台服务器发生数量上的变化时,这种方式不满足哈希单调性,即,节点变化,数据需要重排,大大降低了缓存服务器的可用性。那么一致性哈希能否解决单调性的问题呢?

一致性哈希算法_第5张图片

一致性哈希算法使得哈希单调性的到了最大程度的满足。如上图,假如说,服务器节点C挂掉了,那么这个时候受到影响的必然是原本映射到C服务器上的数据,k3,k4数据需要按照顺时针方向,从新将数据映射到顺时方向的第一个服务器节点上,很显然,k3,k4映射到了D服务器上。从上述变动来看,某些节点的宕机仅仅需要将局部数据进行重排。使得影响最小化。同理,当增加一个数据节点时。处理方式也是一样的

六、可能存在的问题

不管是用一般的取模方法映射数据还是使用二般的分布式一致性算法都面临这数据重排时,数据量过大打爆某一个服务器的问题。哈希另外一个衡量指标是平衡性,平衡性要求,尽量保证所有数据能够均匀的分布,很显然,当某一台机器宕机,相邻存储节点就“遭殃了”。为了解决这个问题,引入虚拟节点概念。虚拟节点实际上是真实的存储节点在空间上的复制品。一个实际节点可以对应多个虚拟节点。

一致性哈希算法_第6张图片

如上图,D1,E1是D和E对应的虚拟节点,在没有虚拟节点之前,K3,K4基于默认规则会存储到D节点上去,那么增加虚拟节点后,我们将数据均衡的分散在了D和E上。也算是分摊了C存储服务器瘫痪引起的问题。


三、Consistent Hashing 一致性hash实现

一致性哈希算法_第7张图片
代码下载地址: https://github.com/HIPROBERT/ConsistentHash.git

你可能感兴趣的:(分布式,算法)