Hash一致性算法理解

在分布式地环境中,集群中大量机器的重启,添加新机器,删除旧的机器是经常发生的事情。如果采用传统的哈希算法将缓存映射到机器,即就是采用如下的方法;

hash(object)%N
上面公式中的object为结果,N为当前集群中机器节点的数目。

采用这种方式有什么缺陷呢?

还是打个比方吧,比如QQ的集群,原来聊天服务在node1机器上,视频聊天在node2机器上,阅读服务在node3机器上,假设现在业务的需要需要添加一台图片存储节点node4。原来聊天时的object都是映射到node1,现在添加一个node4,N发生变化,同样的object可能映射不到node1上,这样就会引起错误,导致业务无法进行。

怎么解决这个问题呢?

这就需要hash一致性算法来解决。

hash一致性算法主要需要满足以下几点:

1、平衡性。内容要尽可能地均匀地分布到所有的机器缓存中,所有缓存空间得以充分地使用;

2、单调性。内容通过hash分派到相应的机器缓存中,现在有新的缓存节点加入,在新节点加入或者旧的节点删除的时候,hash算法应当保证原来内容还是能够映射到原来相应的节点上或者新添加的节点上,而不能映射到旧的其他节点上。

3、分散问题。在分布式集群中,用户向集群中存储数据的时候,不同用户看到机器缓存的范围可能不同,同样的内容可能被映射到不同的机器缓存中,这样就降低了系统的存储效率。所以在设计hash算法时候应当尽量降低分散的问题。
4、负载问题。分散问题是同一个内容可能被不同的用户映射到不同的缓存节点上,那么同样的,一个缓存节点可能被不同用户映射为不同的内容,造成节点的负载加重。所以在实际的hash算法设计中,应当减少这种情况。

在设计一致性hash算法中,为了较好的描述,我们将hash产生的key映射到一个32位长度的环形空间中,如下图所示:


然后我们利用相同的hash函数将用户内容数据与机器节点映射到此hash空间中:


在存储数据的时候,以Hash环,我们按照顺时针的方向,key值找到其最近的node进行存储。比如上面图完整的存储方案:


现在考虑下节点node2挂掉,或者在key4与key3之间添加一个新的节点node4会发生什么情况。

其实节点删除掉后,存储到这个节点上的内容会顺时针迁移到距离其最近的节点上,添加一个节点也是,只是影响其周围的节点,把距离这个节点最近的数据添加进来,依然是按照顺时针方向。



以上的处理方案看似可以完美解决问题,但是这种方案并不完美,看上面node2节点失效的时候,按照顺时针方向存储,节点node3上要负担三个内容数据,负载极高,其他节点存储的确很少,这样就造成了集群中极大的不平衡。为了解决这一点,引入一个虚拟节点的概念。

这个虚拟节点是实际的节点在hash环上的复制,一个实际的节点可以对应于多个“虚拟节点”,这个虚拟节点在hash空间以hash值排列。

为了说明这一点,我们假设开始这个三节点的例程每个节点有两个虚拟节点,则其在hash环中的分布如下:


如果node2失效,则现在的存储情况如下:


现在可以看到实际的物理节点node1与node3各存储2份内容,这样集群中就比较平衡。

为了清晰说明虚拟节点的映射情况可以看看下图:


以上只是对一致性hash算法一个初步的认识,其中的许多东西还需要后面继续玩味!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值