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

场景

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

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

 

一致性hash算法

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第1张图片

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

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

 

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

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第2张图片

  假设我们的集群中有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,所以一定可以映射到。

 

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第3张图片

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

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第4张图片

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第5张图片

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第6张图片

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第7张图片

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第8张图片

LemonAlgorithm: 一种可能和一致性hash算法差不多的分布式存储应用算法_第9张图片

 

总结

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

你可能感兴趣的:(分布式缓存,散列函数,一致性hash,后端,缓存,分布式)