哨兵模式存在一个缺陷,就是主机挂了后,哨兵需要一定的时间进行投票选举出哨兵领导者然后再选择一台从机升级为主机,这段时间的写操作是会丢失的(因为只有主机能进行写操作,从机只能进行读操作)。集群就没有这个缺陷。
槽位slot
集群的密钥空间被分成 16384 个槽,有效地设置了 16384 个主节点的集群大小上限 (但是,建议集群中Redis数量约为 1000 个 )
分片和槽位的优势
slot槽位映射
1.哈希取余分区
优点: 简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。
缺点:原来规划好的节点,进行扩容或者缩容就比较麻烦了,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算。在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化: Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。
某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。
2.一致性哈希算法分区
为了在节点数目发生改变时尽可能少的迁移数据
将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点
优点
加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。
缺点
当集群中的节点数量较少时,可能会出现节点在哈希空间中分布不平衡的问题。如下图所示,图中节点A、B、C分布较为集中,造成hash环的倾斜。数据1、2、3、4、6全部被存储到了节点A上,节点B上只存储了数据5,而节点C上什么数据都没有存储。A、B、C三台机器的负载极其不均衡。
在极端情况下,假如A节点出现故障,存储在A上的数据要全部转移到B上,大量的数据导可能会导致节点B的崩溃,之后A和B上所有的数据向节点C迁移,导致节点C也崩溃,由此导致整个集群宕机。这种情况被称为雪崩效应。
3.哈希槽分区
槽数2^14=16384
Redis为什么选择16384个槽位而不是2^16=65536
参考
一致性哈希算法(consistent hashing) - 知乎 (zhihu.com)