【搞懂】一致性哈希算法

这是【搞懂】系列的第1篇文章,介绍一致性哈希算法

在说一致性哈希算法之前,我们先了解一下我们需要解决的问题和传统解决办法:

考虑以下场景,现在有个流量很大的网站,他们需要使用缓存服务器。(假设网站的流量大到单台缓存服务器无法应对的情况,这个网站后台使用了缓存服务器集群)现在的架构是一共20台缓存服务器,一台转发服务器根据配置将请求的key分配到这20台服务器(分配方法是key的hash值对20取模),半年后,评估发现现有20台服务器无法满足下一轮流量高峰的需要,需要扩容。假设扩容到30台机器,我们顺便假设每个key里都包含了这个key的大概创建时间,当扩容后转发服务器获取key失败时,根据key的创建时间尝试使用旧的配置找到旧的机器重新获取一次(同时把这个key从旧机器搬到新的机器上)。

这个方案看起来不错,但有几个问题:

  1. 转发服务器每次的配置都需要保留,以便key找不到时回溯到之前的服务器(保留的配置早于最大缓存失效时间即可)。
  2. key需要带上时间,以便扩容刚刚结束后查找相应的转发配置信息。
  3. 由20台扩容到30台后,有大约67%的key的最终服务器发生了变动(如果是扩容到25台机器,有80%的key需要移动)。事实上最好的做法是扩容到40台,这样有50%的key需要移动(只要发生扩容,最少有50%的key需要移动机器)。

现在我们来看下使用一致性哈希算法

我们的转发规则不再是用key对机器数取模,而是改成在hash环上分20份。每一份都对应着应一台缓存服务器。假设我们要扩容到30台,在hash环上挑选10个新的hash值(我们挑选20台中负载比较高的10台,在这10台hash环中间取10个hash值),把新的缓存服务器加入集群。转发服务器如果无法找到key就尝试继续向hash环上下一台缓存服务器寻找(找到后如有需要移动这个key)。这个方案上面3个问题解决的如何呢?

  1. 配置不需要保留,回溯服务器的效率和之前的类似。
  2. key没有要求。
  3. 当key的hash分布均匀时,20台扩容到30台时,大约25%的key需要移动(如果扩容为40台,有50%的key需要移动,这是最差的情况)。

对比第3点我们就发现了一致性哈希算法的优越性。一致性哈希算法利用了key哈希值分布的均匀性,牺牲了一点缓存服务器上key分布的均匀性,换来了扩容时最少的key移动

 

一般情况下,大量的key移动是很危险的(增加集群的负载)。

  • 缓存服务器的负载=key的分布 * key使用率

第一种方案没有考虑到key的使用率的情况,每台缓存器上均匀分布着key,但缓存服务器之间的负载也可能不同。

一致性哈希算法在扩容时,允许参考每台缓存服务器的负载情况决定扩容方式,往往能更好的调和各个缓存服务器之间的负载。

posted @ 2020-03-01 18:11  gukz  阅读(305)  评论(1编辑  收藏  举报