一致性哈希

本文章只是浅聊一下一致性哈希算法
首先我们先来看一个分布式缓存的应用场景,了解了这个应用场景,我们就能知道为什么需要用到一致性哈希算法了

假如有3台缓存服务器,并且有3w张图片,并且这3w张图片均匀的缓存在这3台服务器上,这样就能分摊缓存的压力。

在这里插入图片描述

此时我们可以思考一下如何做?了解过hash算法的朋友肯定立马会想到许多方法。在这里我说一下我的方法:简单的做法就是对这些图片通过某些hash算法得到hash值,这个hash值一定是一个整数,再用缓存服务器的数量对这个整数进行取模,最终得到的余数就是要缓存到哪台服务器上,这种方式一定能缓存到服务器上,不可能落空
在这里插入图片描述
因为对同一张图片进行相同的哈希计算时,得到的哈希值是不变的,所以需要访问图片时,只要再次对图片进行哈希计算+取模,就能知道图片存放在哪台服务器上,通过这种方法,就能将3w张图片均匀的缓存在3台服务器上。

虽然这种方法看似完美,但实则不然。
假如现在要在缓存服务器中增加一台缓冲服务器,原来的3台服务器就变为了4台。此时需要访问图片5,先对其进行哈希计算,再取模,得到余数,但是此时的余数是1,表明这个该图片在第1台缓冲服务器上,但实际这张图片在第2台缓存服务器上。这就造成了缓存不命中(缓存失效),不仅是图片5,只要是图片标号大于4的都无法命中,此时就只能访问后台服务器,请求数据。由于大量缓存在同一时间失效,造成缓存奔溃,缓存服务器就无法起到承担缓存压力的作用,压力就转移到后台服务器,就很有可能造成系统的崩溃。

在这里插入图片描述

为了避免这种问题,就需要使用到一致性哈希算法
现在有一个圆环,圆环上均匀分布着2^32个点,这个圆环也被称为哈希环。现在还是有3台服务器,服务器的编号分别为A、B、C。使用它们的编号,分别进行哈希计算,将哈希的结果用 2^32次方进行取模,算出的结果一定是在[0, 2^32]之间的整数,哈希环上必定有一个点与之对应,所以就将该缓存服务器映射到这个哈希环上
在这里插入图片描述
现在有一张图片a.png,通过哈希计算,在用2^32次方取模,映射到哈希环上
在这里插入图片描述
此时a.png和服务器都被映射到哈希环上,此时就该确定a.png应该缓存到哪台缓存服务器上?其实很简单,只用从图片的位置开始,沿着顺时针方向进行查找,遇到的一台缓冲服务器就是a.png应该缓存的服务器。

在这里插入图片描述
根据这样的查找方式,a.png缓存到A上,b.png缓存到B上,c.png缓存到C上。因为被缓存的对象,通过相同哈希计算,值是不变的,在服务器不变的情况下,再次计算就可知道这张图片被缓存到哪台服务器上,只需要在对应的服务器上查找就行。这就是一致性哈希的原理。

再来看一看,一致性哈希能不能解决之前的问题。
假设新增缓存服务器D,按照一次性哈希算法的规则,先将D映射到哈希环上
在这里插入图片描述
从上面这张图可以看出,在增加服务器之前,访问A到B之间的图片,都应该到服务器B中找。但增加服务器D后,A到D之间的图片就应该到服务器D中找,其他的图片还是能正常找到本应该缓存的服务。总的来说,增加服务器,只有少部分缓存失效,大部分还是正常的。

总结一下使用一致性哈希算法的优点:
如果缓存服务器的数量发生改变,并不是所有的缓冲都会失效,而是只有部分缓冲失效,缓冲服务器依旧能缓解整个系统的大部分压力,而不会导致压力在同一时间集中到后台服务器上。

但是一致性哈希算法还有一个缺陷,就是哈希偏斜(数据倾斜)
在介绍一致性哈希算法的原理时,我们理想化的认为3台缓存服务是均匀的映射到哈希环上,但在实际情况中,可能会存在下图所示情况:
在这里插入图片描述

我们将这种情况称为哈希环的偏斜。在这种情况下,大部分的缓存对象很可能缓存到一台缓冲服务器上,导致缓存极度不均匀,3台缓存服务器没有被平均的使用,如果缓存数据较多的缓存服务器出现故障,压力全转移到了后台服务器,很有可能导致系统崩溃。

如何解决这个问题呢?
首先,我们需要明白,出现哈希偏斜的主要原因是服务器没有均匀映射到哈希环上。
其次就是,服务器数量不够多。

解决的方法就是增加一层虚拟结点。虽然服务器的数量有限,但是可以根据真实的服务器来映射许多虚拟的结点,再将这些结点映射到哈希环上。

在这里插入图片描述
虚拟结点越多,哈希环上的服务器结点就越多,缓存被均匀分布的概率也就越大,这样就能一定程度减小哈希偏斜所带来的影响。
具体的,在进行缓存读写时,先找到缓存对应的虚拟结点,再找到真实结点,最后才进行缓存读写。

一致性哈希具有容错性
假设NodeC宕机,可以看到此时对象A、B、D不会受到影响。一般的,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着道时针方向行走遇到的第一 台服务器)之间数据, 其它不会受到影响。 简单说,就是C挂了, 受到影响的只是B、C之间的数据且这些数据会转移到D进行存储。

在这里插入图片描述

一致性哈希具有扩展性
数据量增加了,需要增加一台节点NodeX,X的位置在A和B之间,那收到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,不会导致hash取余全部数据重新洗牌。

在这里插入图片描述

  • 19
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值