一、hash算法
我们有3w条数据要放在3台redis服务器上,根据id或者其他关键字进行hash取模,分布到A,B,C这3台机器上。
hash(id)% N
N为redis服务器数量。
但是这样有什么问题呢?
1.数据分配不均匀,可能大部分数据都集中到一台机器上。
2.当其中一台机器宕掉的话或者数据量越来越大增加一台服务器的话,那么所有数据都要重新hash取模,导致大量缓存数据失效,可能同时打到数据库上,从而造成雪崩的情况。
二、hash一致性算法
这个hash一致性算法有个环形空间的概念,将value映射到32位的key值内,首尾相连形成一个圆形,取值范围为0~2^32-1。
现在还是3台服务器,
然后一个对象进行hash获取对应的key值比如key1,顺时针找最先找到的节点事cacheA,那么数据就缓存再A服务器上。
那么这时候有一台服务宕机了,比如cacheA。那么key1顺时针找到的节点就是cacheB了,那么受影响的数据只有本来应该在cacheA的数据全部转移到cacheB上去了,影响的数据就少了,不会造成大量缓存数据失效。
问题2解决了,但问题1还是没法解决,数据可能还是会集中到某一台机器上。这就是hash倾斜性的问题,hash无法保证数据均匀分布。
为此引入了虚拟节点,一个真实节点对应多个虚拟节点。引入虚拟节点后,对象不是直接映射到真实节点上,而是虚拟节点。再通过虚拟节点映射到真实节点。
这样数据就更均匀分布了。当服务器数量越多,节点越多,数据就越分布均匀。