形象比喻,一致性哈希应该怎么理解?

形象比喻,一致性哈希应该怎么理解?

传统哈希算法在需要扩桶的时候需要对全部元素重新移动,这个过程叫做重哈希(rehash)。扩桶意味着当前桶的数量不足以装下所有的元素,所以这个移动代价一定是很高的,要保证这么多数据迁移不出错,不影响现有使用,需要注意很多方面。那么,有没有一种算法能兼容现有的哈希算法,使得新的元素可以均匀发布到各个桶里,旧的元素仍存放在之前的位置呢?答案是有的,这就是一致性哈希。接下来我们就看看一致性的具体表现。

工作原理

如果要保证扩桶不影响当前元素的哈希映射关系,我们首先就会明白这种哈希算法不应该是怎样的——哈希算法不应该跟桶的数量相关。回想一下常见的哈希表最终都需要对桶的数量取模,这样才知道具体分到哪个桶。如果要避免跟桶的数量相关,我们就不能采用直接取模的办法,而应该用一种间接的办法找到对应的桶。

我们可以用生活中的地址来类比,我们可以准确知道小明家、社区的经纬度坐标,同时也可以知道小明家和社区的相对方位和距离。假如后续这个区域居民越来越多,一个社区的房间有限,人们排队时间也长。原社区在北边,此时社区就会拆分,一南一北,这样每个社区每日承担的服务人数就比较均衡了,南北两个社区都只用服务当前半径范围内5km的居民。

  • 假设小明家在南边,原来还需要跑到北边的社区去咨询办事,现在只需在离家近的南边社区处理了;

  • 假设小明家在北边,现在还是去北边的社区,南边的社区与他无关。

  • 原社区的居民同小明家的情况,北边的居民还是去以前的地方,南边的居民可以去更近的南边社区。每个社区的管辖范围不同,其他社区不受这个社区变化的影响。

一致性哈希中的桶就如同社区,每个元素就是居民。一致性哈希中还有个哈希环,这个就如同我们生活的地球。在地球上有很多居民和社区,正如在哈希环上有很多元素和桶。我们通过唯一不变的哈希算法找到每个元素和桶在哈希环上的位置,也就相当于居民和社区的经纬度坐标。

如下图所示,假设两个桶之间的元素都按顺时针去找所归属的桶,那么当桶A、桶B中间加入新的桶C时,A和C之间的元素1现在不能存在桶B里了,而需要移动到桶C中。但是B和C之间的元素2,以及其他无关元素3不用移动。

假设要删除桶C,元素1移回桶B,其他元素不用动。

可以看出,相比于之前直接取模需要全局的数据迁移,使用一致性哈希算法将只影响变动的桶和左侧上一个桶之间的数据,大大减轻了压力。

说了基本的工作原理,那么哈希环到底是什么呢?其实哈希环可以理解为一个整数区间 [ 0 , 2 32 ] [0,2^{32}] [0,232]。在环上, 2 32 2^{32} 232的右侧就是0,这样就可以构成闭环。我们利用统一的哈希算法将每一个元素和节点(桶)映射到某一个整数,就是哈希环上的位置。

虚拟节点

和普通的哈希算法一样,一致性哈希也会遇到数据倾斜的问题,即某一两个桶拥有了过多的元素,负载因子偏大。普通哈希的解决办法是多加一些桶,一致性哈希也是同理,多加几个节点即可。在没有足够的真实节点时,一致性哈希还可以利用虚拟节点来平衡,比如下图,假如没有虚拟节点,2、4、5、6都归属节点B,1、3归属节点B。现在通过虚拟节点A’和虚拟节点B’,让2、3、5都归属节点A,1、4、6归属节点B,有了虚拟节点的帮助,我们就可以平衡这一局面。


如今互联网上各类文章满天飞,但是大部分要不是寥寥数语,让人过目即忘;要不是过多细枝末节又没有实操,让人不知所云。我将从个人学习和工作经历出发,给大家带来深入浅出的技术解析。我的文章力求简短精悍,尽量结合实战,以便大家在碎片时间即可充分吸收,后续还能学以致用。

欢迎大家关注我的微信公众号,所有文章第一时间更新~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值