一致性哈希算法

一致性哈希算法(consistent hashing)

假设背景

我们有大量的资源需要分别储存到三台服务器上,这三台服务器为A、B、C服务器。最简单的做法就是随机地平均地将资源分配到这三台服务器上,这样既满足了存储的要求又使每台服务器受到压力相近。但是有一个问题:我们该如何从这三台服务器中查找所需要的资源?三台服务器都遍历一遍?这样的效率无疑是低下的,尤其是当这种服务器数量不止三台的时候。这个时候我们用下面的方法来解决这种问题。

为了方便描述,我们假设这种资源是图片。每张图片有不同的名称且名称不重复。

方法一

对每张图片的名称做哈希计算,将结果对3取余,结果只有三种情况0、1、2。所以我们就将每张图片名称最后哈希取余的结果放到对应的服务器上(在一开始我们就假设了A、B、C服务器)。

这样,我们可以将所以的图片分配到三台服务器上,且在读取时我们也只需要使用上面的计算方式,就可以知道每张图片所存放的服务器。所以我们就只需要遍历三台中一台服务器就能找到所需要找的图片。

但是这样会有什么问题呢?如果服务器数量发生变化,原来图片存放的服务器可能需要改变(几乎所有位置),这样会带来很大的影响。所以我们就有了下面这种方法——一致性哈希算法。

方法二

首先,对每台服务器的ip地址进行哈希,之后将结果对 232 2 32 进行取模。这样我们就一定能得到三个完全不一样的结果且在 0 0 2321之间。有一个问题,为什么是对 232 2 32 取模?因为ip地址是最多有 232 2 32 个。从0.0.0.0到255.255.255.255,排列组合得到的所有可能地址。

接下来,我们想象一个圆环,这个圆环从任意一点开始再回到这个点,其中所有的点都是由 0 0 2321构成。这样这个圆环就有 232 2 32 个点,我们将这个圆环称作hash环。接下来我们将刚刚三台服务器ip地址运算的结果代入进这个hash环中。

之后,我们用方法一中的方法。将每张图片名称做哈希计算,将结果对 232 2 32 取模,最后得到一个值。我们将这个值放到hash环上,以这个点为出发点顺时针旋转,之后遇到的第一个服务器的点,遇到了A服务器,就将这张图片放到A服务器上。总结来说,就是对图片名称做运算,得到的结果放在hash环上,顺时针方向离的最近的服务器就是图片的存储服务器。

大功告成,以上就是图片的存储方法。如果需要读取,也可以通过上面的计算方式找到存储的服务器。那么这样是否还会有方法一的问题吗?假设我们现在移除了一台服务器,所以我们在hash环上对应的服务器点去除,然后将服务器上的所有图片,存放到离它顺时针最近的服务器上。这样并不会改变所有图片的存储位置,带来影响比方法一小了很多。当然,我们也可以做增添一台服务器的假设,过程基本同上。

但是,这样会有什么问题呢?最明显的一个缺点就是没办法保证服务器所受压力相同,换句话说,某台服务器上可能有很多很多图片,而另一台服务器上可能没有几张图片。为了解决这个问题,就有了下面的方法三。

方法三

刚刚方法二的问题用一种专业(装逼)词汇来说就是hash环的偏斜,为了解决这种偏斜,我们可以引入虚拟节点

原来我们只有A、B、C三台服务器,那么我们可以在此基础上模拟我们又多了三台服务器A1、B1、C1。原来的服务器我们称为实际节点,模拟出来的我们称为虚拟节点,虚拟节点是实际节点复制而来。我们将这些虚拟节点放在hash环上,这样就可以使节点在hash环上的分布稍微均匀一点,如果有需要可以继续进行复制出更多的虚拟节点。当图片进行存储的时候,如果顺时针遇到的第一个节点为虚拟节点,则将该图片存储到该虚拟节点原有的实际节点中。虚拟节点越多,节点分布地就越均匀,每台实际服务器上的压力也越均衡。

虚拟节点的数量,是原有服务器数量的n倍,这样才能保证分布均匀。虚拟节点放置的位置应该是由实际节点的位置旋转而来。换句话说,A1、B1、C1三个虚拟节点之间的距离应该与实际节点的相同。

参考文章 :
白话解析:一致性哈希算法 consistent hashing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值