一致性哈希算法

上周参加了拼多多的实习生面试,面试官针对我的分布式kv存储项目问到一个问题:
你是如何实现请求数据和分片节点之间的映射关系的?
答:我的项目中实际用到的是通过将对应关系存储起来,将这个配置关系作为一个服务也通过raft进行同步,我可以从这个服务中获取到分片所属的group集群,以及group集群对应的服务节点信息。
面试官又问到:还有其他方式吗?
这时我想到之前看到过的一致性哈希算法,一致性哈希算法和普通的哈希算法有什么区别呢?哈希环如何构建的呢?如何解决节点分布不均匀的问题呢?这篇文章给你做出解答。


1. 普通的哈希算法有什么问题

如果节点数量发生了变化,也就是在对系统做扩容或者缩容时,必须迁移改变了映射关系的数据。
最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了。
通过一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题。
在这里插入图片描述

2. 一致性哈希算法原理

2.1 哈希环如何形成

哈希算法是对节点的数量进行取模运算,而一致哈希算法是对 2^32 进行取模运算,是一个固定的值。
image.pngimage.png
一致性哈希要进行两步哈希:

  • 第一步:对存储节点进行哈希计算,也就是对存储节点做哈希映射,比如根据节点的 IP 地址进行哈希;
  • 第二步:当对数据进行存储或访问时,对数据进行哈希映射;

所以,一致性哈希是指将「存储节点」和「数据」都映射到一个首尾相连的哈希环上。
对「数据」进行哈希映射得到的结果值往顺时针的方向找到第一个节点,就是存储该数据的节点。

2.2 如何进行数据读写

所以,当需要对指定 key 的值进行读写的时候,要通过下面 2 步进行寻址:

  • 首先,对 key 进行哈希计算,确定此 key 在环上的位置;
  • 然后,从这个位置沿着顺时针方向走,遇到的第一个节点就是存储 key 的节点。
2.3 增加或者减少节点情况

下图中新增节点D,可以看到只会影响key2
image.png
下图中删除节点A可以看到只会影响key1
image.png
在一致哈希算法中,如果增加或者移除一个节点,仅影响该节点在哈希环上顺时针相邻的后继节点,其它数据也不会受到影响。

3. 如何通过虚拟节点提高均衡度

一致性哈希算法虽然减少了数据迁移量,但是存在节点分布不均匀的问题。
要想解决节点能在哈希环上分配不均匀的问题,就是要有大量的节点,节点数越多,哈希环上的节点分布的就越均匀。
我们使用虚拟节点,也就是对一个真实节点做多个副本。具体做法是,不再将真实节点映射到哈希环上,而是(1)将虚拟节点映射到哈希环上,请求数据映射到虚拟节点(2)将虚拟节点映射到实际节点,所以这里有「两层」映射关系。
比如对每个节点分别设置 3 个虚拟节点:

  • 对节点 A 加上编号来作为虚拟节点:A-01、A-02、A-03
  • 对节点 B 加上编号来作为虚拟节点:B-01、B-02、B-03
  • 对节点 C 加上编号来作为虚拟节点:C-01、C-02、C-03

image.png
节点数量多了后,节点在哈希环上的分布就相对均匀了。这时候,如果有访问请求寻址到「A-01」这个虚拟节点,接着再通过「A-01」虚拟节点找到真实节点 A,这样请求就能访问到真实节点 A 了。
除了解决真实分布不均匀的问题,引入虚拟节点还有什么好处?
另外,虚拟节点除了会提高节点的均衡度,还会提高系统的稳定性。当节点变化时,会有不同的节点共同分担系统的变化,因此稳定性更高。比如,当某个节点被移除时,对应该节点的多个虚拟节点均会移除,而这些虚拟节点按顺时针方向的下一个虚拟节点,可能会对应不同的真实节点,即这些不同的真实节点共同分担了节点变化导致的压力。

参考资料:
小林coding网站
如果你想更加深入理解一致性哈希算法我推荐你也可以看一下小小徐先生的博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值