Redis分布式解决方案 (consistent hash)
分类:
文章
•
2025-03-14 15:02:33
传统的redis分布式算法:
比如现在有一个数据,使用redis存储时,会现将其进行hash计算,然后根据计算的hash值进行取模,根据取模的结果将数据缓存到与结果值对应的redis中。算法如下:

案例1:传统分布式算法
使用传统的redis分布式算法的结果如下:根据取模的结果,将数据存储到相应的redis中

现在由于业务的需求,我们需要添加一台redis,添加后。就变成了5台redis,那么5台redis的一定会比4台的效果要好吗?
增加一台redis后,20个数据的结果如下。
增加一台redis后,出现以下结论:(4台redis和5台redis比较得出的结论)
redis0:只有20号数据命中
redis1:只有1号数据命中
redis2:只有2号数据命中
redis3:只有3号数据命中
根据数据命中,得出的命中率为: 4/20 =20%
命中率为20%,这是极低的,很容易击穿缓存到达数据库,这显然是不行的。
那为什么增加了redis,反而命中率降低了呢?
因为算法的局限性
我们看第二种算法 ------------------------ Consistent Hashing (哈希一致性算法)
Consistent Hashing (哈希一致性算法)

这个算法引入了一个新的概念: 环形hash空间 (空间的取值范围为: 0到 2的32次方减1)

传统的算法是进行取模缓存,这个算法是将数据进行hash计算,然后将计算的hash映射到hash空间上
我们以4个数据为例:
这个算法先将数据映射到hash空间中,然后将cache(redis)也映射到hash空间中
我们以三个redis为例:映射后如图所示:
现在数据和cache都映射到了hash空间中,那么如何将数据存储到cache呢?
算法的数据存储是按照hash空间环 顺时针 存储(将数据存储到顺时针遇到的第一个cache中)如图所示:

那这种算法好在哪里呢?
比如我们现在移除或添加一台cache,那么数据还是按照顺时针存储到数据库中:如图所示:
比如移除cacheB
移除后并不会对object4造成影响,它继续顺时针移动到cacheC中
再比如添加一个Cache

依然不会造成影响,依然按照顺时针移动到相应的cache中
但是问题来了,既然是顺时针存储,那么cache分布均匀还好,这样数据可以均匀分布,也能充分利用cache

但是,如果cache分布不均匀呢?(不均匀是hash算法的倾斜行导致的)

像这样分布的话,cacheA的压力就非常大,显然是不合理的
那么如何解决呢?
可以使用虚拟节点的方式来解决:

比如一个cache有两个虚拟节点,当数据命中到节点上时,将数据存储到相应的真实的cache中。
使用虚拟节点来解决分布均匀问题:

这样就可以很好的解决问题,既可以增加Cache有可以移除Cache,不会影响到性能