一、余数hash
简单的路由算法可以使用余数算法,使用redis集群服务器数量除以对应key的hash值,余数为所属服务器列表下标。由于hash值随机,每台服务器存储的key值大致平均,对此算法稍加改进也可以实现加权负载均衡。
但是缺点是如果扩容的话,会相对棘手,假设原本有3台服务器,此时增加一台服务器,变为4台服务器,此时原本hash为 201的值原本 201 % 3 为0的此时变为201%4,对应服务器下标为1,必然会照成大部分key打到另外的服务器上,而服务器上并没有数据,会对数据库照成很大的压力。一般情况下这种方式会选择在服务访问比较少的时间段,例如深夜,并且模拟请求逐步将缓存缓存到各个服务器上。相对比较麻烦。
二、分布式缓存一致性hash算法
一致性hash算法通过一种叫做一致性hash环的数据结构实现key到缓存服务器上的映射。
具体算法为先构造一个长度为0-2^32的整数环(称做hash环),根据节点名称的hash值(值范围也为0~2^32)将缓存服务器的节点放到hash环上。再根据key值到到对应hash环上顺时针查找第一个服务器。完成key到服务器的hash映射查找。
当缓存服务器需要扩容时,只需要将新加入的服务器的节点放到hash环中即可,因为key值是按照顺时针查找第一个服务器,因此只会影响环中的一小段,其余不受影响。
但是此种方式会有一个小问题,就是假设新加入的节点node3只影响原来的节点node1,那么理论上不受影响的节点node0,node2上所存储的字段为新加服务器节点的2倍。此问题可以通过增加虚拟节点的方式解决。