最容易理解的Consistent Hashing讲解(一致性哈希算法使用场景及原理)

一、使用场景

        考虑一个场景,有一个redis集群,那么我们如何分配不同的要缓存的数据,使之能够尽可能均匀的存储到各个redis服务器上呢?肯定有人会想到使用传统的hash + 取模 算法。

        服务器ID = hash(object) % N                    (N为服务器个数)

        举个例子,如果我们有4个redis服务器,编号分别为0,1,2和3,产生的十个数据的hash值分别为1~10。列出具体的数据分布情况。

        0号服务器:4、8

        1号服务器:1、5、9

        2号服务器:2、6、10

        3号服务器:3、7、11

        首先我们不管分布的是否均匀,我假设一种情况,如果多加一个节点,即4号服务器,那么这些数据是要重新分布的,重新分布的结果我们来看一下。

        0号服务器:5、10

        1号服务器:1、6

        2号服务器:2、7

        3号服务器:3、8

        4号服务器:4、9

        可以看到,除了1、2、3这三个数据,其他数据的缓存位置都发生了变化,这样会导致很严重的性能问题。

        这时候我们的一致性哈希算法就出场了。该算法的目的是在移除/新增一个节点时,尽可能减少“缓存数据key”到服务器映射的改变。

(1)首先要构造一个环形hash值区域,一般值区域为0~2^32-1。

(2)对key的值求hash值,h1 = hash(key),将该值放入环形hash区域的某个桶中。

(3)对每个redis服务器的编号值(可以是IP,也可以是其他某个标识符)求hash值,h2 = hash(node),将该值放入环形hash区域的某个桶中。

(4)每个缓存数据都缓存在它前方(hash环顺时针方向的前方)的redis服务器中。


            (图片来自网络)

        这样就完美解决了之前因为新增/移除节点而导致的数据缓存位置大幅度移动的情况,因为每个节点所在的hash桶的位置都是固定不变的,而且每个数据所在的hash桶位置也是不变的。因此如果在两个节点如图中的A1和C2之间再插入一个节点X,则若是X插入的位置在key2的位置的前面(A1与key2)之间,则整个图只需要移动key2的缓存位置,让object2缓存到X就行,如果X节点的插入位置在key2 和C2之间,则不需要移动任何缓存数据。

        但是这样还是有缺陷的,可能会存在hash分布不均匀的情况,那就需要虚拟节点,因为在hash环上,节点越多,分布的会更均匀。


(图片来自网络)

        在图中有v1~v6若干个节点,缓存数据都会分布在这几个节点上,但这都是虚拟的,缓存数据实际存储的位置时n1~n3,这样会使得缓存分布更加均匀。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值