一个集群模式的官方推荐最小最佳实践方案是 6 个节点,3 个 Master 3 个 Slave 的模式,如 图00 所示。node
Redis 将键空间分为了 16384 个槽,经过如下算法肯定每个 key 的槽:git
CRC16(key) mod 16384
因为 16384 = 2 的 14 次方,对一个 2 的 n 次方取余至关于对于它的 2 的 n 次方减一取与运算。因此优化为:github
CRC16(key) & 16383
当 key 包含 hash tags 的时候(例如 key{sub}1
),会以 sub tags 中指定的字符串(就是 sub )计算槽,因此key{sub}1
和key{sub}2
会到同一个槽中。redis
客户端能够发送读取任一个槽的命令到任一个集群实例,当槽属于请求的实例的时候,就会处理,不然会告诉客户端这个槽在哪里,例如若是将下面命令发到第二个 Master:算法
GET key1 返回: MOVED slot ip:port(第一个Master的)
默认状况下,全部的读写命令只能发送到 Master。若是须要使用 Slave 处理读请求,须要先在客户端执行 readonly
命令。ide
当一个 Master 发生故障,若是有 Slave,则会切换为 Master。函数
如何判断 Master 发生故障了呢?Redis 集群配置中有一个配置,cluster-node-timeout
集群心跳超时时间。当集群内节点创建链接后,定时任务 clusterCron 函数(参考源码:https://github.com/redis/redis/blob/6.0/src/cluster.c)会每隔一秒随机选择一个节点发送心跳。若是在超时时间(cluster-node-timeout
)的时间内未收到心跳响应,则将这个节点标记为 pfail。优化
若是集群中有一半以上的 Master 标记一个节点的状态是 pfail,那么这个节点的状态就会变成 fail。code
当节点变成 fail 就会触发自动主从切换。主从切换的过程,也涉及到相似的选举:blog
根据上面的描述,咱们能够总结出以下不可用的状况
每日一刷,轻松提高技术,斩获各类offer: