1.取模算法
这种算法非常的简单,就是根据服务器台数的余数进行分散,求得整数值的hash值,再除以服务器的台数,根据其余数来选择服务器,将server的hash值与server的总台数进行求余,即hash%N。
但是在这种算法对缓存命中率的影响下:
我们假设有8台服务器,运行中突然down了一台,则求余的底数变成了7,那么其产生的结果就完全变了
一般地,我们从数学上归纳之:
有N台服务器,变成了N-1台服务器,所以命中率在服务器down的短期内,急剧下降至1/(N-1),所以服务器越多,则down机的后果越严重
2.一致性hash算法
为了解决上述取模算法遇到的问题,我们可以使用另一种分布式算法,即一致性hash算法,所谓的一致性hash算法,就是把服务器的各个节点放在钟表的各个时刻上,同时,我们也将要存储的key也映射到钟表的某个时刻上,该key延钟表顺时针走,碰到第一个比他小的节点之后,则key就落在这台服务器上
补充:利用crc32()函数可以将key值转换成整数
当某个节点down后,只影响该节点顺时针之后的1个节点,而其他节点不受影响
我们通过上图看到,6号节点down后,所有的压力都转移到7号节点上,造成了7号节点服务器的压力特别的大,那我们考虑是否能够将6号节点的压力注意到其余的节点上?
所以我们引入了虚拟节点的概念:
虚拟节点-N个真实节点,把每个真实节点映射成M个虚拟节点, 再把M*N个虚拟节点,散列在圆环上. 各真实节点对应的虚拟节点相互交错分布,这样某个真实节点down后,则把其影响平均分担到其他所有节点上