我们在使用Redis的过程中,为了保证Redis的高可用,我们一般会对Redis做主从复制,组成Master-Master
或者Master-Slave
的形式,进行数据的读写分离
当缓存数据量超过一定的数量时,我们就要对Redis集群做分库分表的操作。
来个栗子,我们有一个电商平台,需要使用Redis存储商品的图片资源,存储的格式为键值对,key值为图片名称,Value为该图片所在的文件服务器的路径,我们需要根据文件名,查找到文件所在的文件服务器上的路径,我们的图片数量大概在3000w左右,按照我们的规则进行分库,规则就是随机分配的,我们以每台服务器存500w的数量,部署12台缓存服务器,并且进行主从复制product.png
,由于我们有6台主服务器,所以计算的公式为:hash(product.png) % 6 = 5
, 我们就可以定位到是5号主从,这们就省去了遍历所有服务器的时间,从而大大提升了性能。在上述hash取模的过程中,我们虽然不需要对所有Redis服务器进行遍历而提升了性能。但是,使用Hash算法缓存时会出现一些问题,Redis服务器变动时,所有缓存的位置都会发生改变
。
比如,现在我们的Redis缓存服务器增加到了8台,我们计算的公式从hash(product.png) % 6 = 5
变成了hash(product.png) % 8 = ?
结果肯定不是原来的5了。
再者,6台的服务器集群中,当某个主从群出现故障时,无法进行缓存,那我们需要把故障机器移除,所以取模数又会从6变成了5。我们计算的公式也会变化。
由于上面hash算法是使用取模来进行缓存的,为了规避上述情况,Hash一致性算法就诞生了~~
一致性Hash算法也是使用取模的方法,不过,上述的取模方法是对服务器的数量进行取模,而一致性的Hash算法是对2的32方
取模。即,一致性Hash算法将整个Hash空间组织成一个虚拟的圆环,Hash函数的值空间为0 ~ 2^32 - 1(一个32位无符号整型)
,整个哈希环如下:
顺时针方向组织
,圆环正上方的点代表0,0点右侧的第一个点代表1,以此类推。
现在,我们使用以下算法定位数据访问到相应的服务器:
将数据Key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针查找,遇到的服务器就是其应该定位到的服务器。
例如,现在有ObjectA,ObjectB,ObjectC三个数据对象,经过哈希计算后,在环空间上的位置如下:
根据一致性算法,Object -> NodeA,ObjectB -> NodeB, ObjectC -> NodeC
原文:https://www.cnblogs.com/tracydzf/p/12907511.html