LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法

2 篇文章 0 订阅
1 篇文章 0 订阅

场景

  以分布式缓存为例,我们需要在多台机器上分别存储不同的缓存,从而降低单一机器的负担。最常见的做法是通过hash算法,计算缓存key的哈希值,然后再对机器数量取余,从而将缓存分散到不同的机器上,以达到同一份缓存每次都会访问固定机器的目标。

  但是在增加一台机器,或者减少一条机器的时候,对机器取余,就会造成大量的缓存不能访问原来的机器,很可能会引起缓存雪崩效应,进而造成服务器宕机。

 

一致性hash算法

图来源: https://www.cnblogs.com/williamjie/p/9477852.html

图应该是比较直观的,环上的大圆表示机器,小圆表示数据。机器(node节点)hash之后,映射到环上一个固定的位置。数据也同样,hash之后,顺时针选取最近的机器节点存储数据。图中,添加node5节点(机器),映射到的位置再node2和node4节点之间,索引node2和node5之间的数据都需要发生变化,具体是: 原来存储的是node4节点,现在存储的是node5节点,因为对这部分数据而言,顺时针更靠近node5节点,所以存储到node5中。

 

一种可能和一致性hash差不多的算法                -- lemon algorithm

  假设我们的集群中有N台机器,我们的第一个变量firstMod为大于N的2的m次方,第二个变量secondMod为firstMod的一半。比如我们有8台机器,那么大于8的2的幂次方就是16,secondMod则为8;如果我们有5台机器,那么firstMod=8,secondMod=4.

  还是以场景中的常规做法为例,我们计算缓存key的hash值之后,对“机器”取余,当然此处的“机器”,不是真实的机器数量,否则我也不会写这篇文章了。我们用缓存key的hash值对firstMod取余,从而映射到不同的机器。比如缓存key计算出的hash值为23,那么以8台机器为例,firstMod=16,取余为7,那么就将这份缓存存储到7号机器上。对于余数为0的,固定存储到1号机器上。

  可能有的同学发现了,当缓存key为25时,以8台机器为例,firstMod=16,取余为9,没有对应的9号机器。所以我们的第二步就是用余数和最大的机器号进行比较,如果大于最大的机器号,即没有机器可以存储,那么就用余数再对secondMod取余,这样便一定有可对应的机器。还是以8台机器为例,hash值为25,对firstMod=16取余为9,大于最大的机器号8,再取余为1,所以映射到1号机器上。有没有可能对secondMod取余没有相应的机器呢?因为我们的firstMod为最靠近且大于机器数量machine的2的m次方,所以

firstMod < (machine << 1),故secondMod肯定小于machine,所以一定可以映射到。

 

  上图以8台机器扩容到9台机器为例,需要搬移的数据仅hash值为9的,其与均不变,也就是变了1/16,这个大概和一致性hash差不多,最重要的是,不会引起缓存雪崩,而又分布比较均匀。上图中mod8一列,红色标记的为需要二次取余的hash值。X表示本次扩容需要搬移的数据。下面为几张扩容示意图:

 

总结

  计算量仅为两次取余和一次比较,所以性能上不会有问题。对于分布均匀的问题,前面我们提到余数为0(整除),固定存储到1号机器上,但是这样1号机器上压力比较大,初步设想是可以存到secondMod机器上,secondMod对应的机器也是一定存在的,这样相对分散一点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值