怎么知道故障了呢?
- 每个哨兵会定期向所有redis节点周期性发送ping消息以检测其状态
- 若一节点在一定时间内未响应该ping消息,则哨兵认为该主节点为主观下线(S_DOWN)
- 为确认该节点确实不可用,集群中哨兵需要达成共识。在达到配置的投票数量情况下,标记为客观下线(O_DOWN)
此外在哨兵故障检测之外还存有节点自检,目的在于确保节点间通信正常,维护集群状态。自检不执行恢复,仅广播状态,标记主观下线(PFAIL)
故障之后会怎么处理呢?
若故障节点为主节点,集群尝试从主节点的从节点中选取新主节点
- 从节点广播到其他主节点请求投票
- 主节点根据从节点优先级、复制偏移量、延迟稳定性等因素进行投票
- 在从节点收到大多数主节点的ACK后,就会选举为新的主节点,并传播新主从关系以及选举期到集群中其他节点
- 若在
2 * NODE_TIMEOUT
时间内未达到多数,则终止选举,并在4 * NODE_TIMEOUT
内进行再次选举
会不会存在一个从节点收到了同主节点的两轮选举的投票呢?
不会。从节点会计算选举期,若获取的票不在本轮选举中,则不会进行计数
同一主节点是否可以给多个从节点投票呢?
不可以。
-
主节点拒绝对旧的选举期投票
-
主节点在投票一次后,在
2 * NODE_TIMEOUT
时间内不能再对竞选同一主节点的候选者进行投票
从节点能否知道主节点下线的时候立刻发起投票呢?
从节点必须等待Delay时间后,尝试进行选举。以保证其他主节点知晓该主节点已经下线,并且防止从节点同时启动选举
d e l a y = 500 m i l l i s e c o n d s + r a n d o m d e l a y b e t w e e n 0 a n d 500 m i l l i s e c o n d s + R E P L I C A R A N K ∗ 1000 m i l l i s e c o n d s delay = 500 milliseconds + random delay between 0 and 500 milliseconds + REPLICA_RANK * 1000 milliseconds delay=500milliseconds+randomdelaybetween0and500milliseconds+REPLICARANK∗1000milliseconds
如果手动配置新主节点或者槽迁移恰好碰上了故障选举,使得同一选举期存在多个主节点,那么该如何处理冲突呢?
NodeID字典序更小的节点将成为唯一的主节点,并递增选举期
集群扩容过程是什么样的呢?
- 加入新节点到集群:在集群中任意客户端执行meet
- 迁移槽
- 确定哪些槽需要被迁移到目标节点
- 获取槽中key
- 将槽中的key全部迁移到目标节点
- 向集群所有主节点广播槽(数据)全部迁移到了目标节点
数据迁移时,客户端如何访问到原节点的数据呢?
- 若数据仍然在原节点中,未进行迁移,则直接访问原节点数据
- 若数据仍然在原节点中,但进行迁移,则返回特殊的ASK重定向,指示客户端向新的目标节点访问
- 若数据完全迁移到新目标节点中,则返回MOVED重定向错误,指示客户端hash槽已经永久迁移到新节点
Ref
- https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/