一致性哈希

问题背景

假设有N台redis作为缓存,传统的Hash算法是:ser = hash(k) % N,即对键值哈希,然后对服务器的个数取余,这样做简单、而且分布均匀,但是有两个问题:
- 假设有服务器x发生了宕机,那么此时取余命中x是失效的,我们需要对键值进行相应的迁移,把服务器变成N-1台,但是这样面临服务器一定时间不可用的情况,造成redis雪崩
- 假设容量不够,我们需要扩容,此时新加入服务器后,也需要改变为N + 1,同样有迁移key造成雪崩的问题。

综上可知,取余的哈希的核心缺陷在于:服务器变动后,会影响N,造成整体key的迁移

解决方案

N变化是造成整体不可用的核心原因,最容易想到的方式是:

  • 固定住N,不会因为几个服务器的变动影响整个集群
  • 发生服务器变动时,使得key迁移的变动尽可能小

N = 2 32 − 1 N=2^{32}-1 N=2321,然后对每个服务的IP或者其它的值进行哈希取余,使这些数据分布在0-N的一个圆环上。之后对key取余,然后顺时针的对应到相应的服务器上,如下图:

在哈希环上的值,按照顺时针方向,去寻找自己的服务器,这样就可以找到对应的服务了。

为什么一致性哈希可以解决传统方式的雪崩问题:
假设下面一个场景,服务器C崩溃,此时请求C的哈希值,会落在D上,而请求A、B、D的服务不会发生变化,制造成了1/4的不可用。同样的,假设加入服务器X在A和B之间,此时请求B的服务,会有一部分去X上,也是影响了部分的流量。通过一致性哈希的方式,把影响降到了最小。参考下面两个图:

一致性哈希的不足与缓解方案

一致性哈希相对于传统哈希来说,最大的缺陷在于服务数量少的时候,可能造成请求不均衡的情况,比如下面这个图片:

大量的数据都去了节点A,只有少部分数据在节点B上。

缓解方案:

  • 修正服务的映射方式,使得服务器在哈希环上尽可能均匀分布
  • 使用虚拟节点,增加二级映射的方式。虚拟机节点缓解分布的问题,手动映射虚拟节点到实际节点。如下图:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值