三个定时任务
-
每10秒每个sentinel对master和slave执行info
发现slave节点
确认主从关系
-
每2秒每个sentinel通过master节点的channel(频道)交换信息(pub/sub)
通过_sentinel_:hello频道交互
交互对节点的“看法”和自身信息
-
每1秒每个sentinel对其他sentinel和redis执行ping
心跳检测,失败判断依据
主观下线和客观下线
主观下线
每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过 down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。
相应配置如下:
sentinel down-after-milliseconds <master-name> <times>
sentinel down-after-milliseconds mymaster 30000
客观下线
当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is-master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过 quorum 个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定;即是大部分 Sentinel节点都对主节点的下线做了同意的判定,那么就是客观下线。
sentinel monitor <masterName> <ip> <port> <quorum>
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
sentinel is-master-down-by-addr 127.0.0.1 6379 0 *
- ip:主节点IP
- port:主节点端口
- current_epoch:当前配置纪元
- runid:此参数有两种类型,不同类型决定了此API作用的不同
当runid等于“*”时,作用是Sentinel节点直接交换对主节点下线的判定。
当runid等于当前Sentinel节点的runid时,作用是当前Sentinel节点希望目标Sentinel节 点同意自己成为领导者的请求,有关Sentinel领导者选举,后面会进行介绍。
例如sentinel-1节点对主节点做主观下线后,会向其余Sentinel节点(假设 sentinel-2 和 sentinel-3 节点)发送该命令:
sentinel is-master-down-by-addr 127.0.0.1 6379 0 *
返回结果包含三个参数:
- down_state:目标Sentinel节点对于主节点的下线判断,1是下线,0是在线。
- leader_runid:当leader_runid等于“*”时,代表返回结果是用来做主节点是否不可达;当leader_runid等于具体的runid,代表目标节点统一runid称为领导者。
- leader_epoch:领导者纪元。
领导者选举
- 原因:只有一个sentinel节点完成故障转移
- 选举:通过sentinel is-master-down-by-addr命令都希望成为领导者
Sentinel 领导者选举的大致思路:
- 每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观 下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求将自己设置为领导者。
- 收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝。
- 如果该Sentinel节点发现自己的票数已经大于等于max(quorum,num(sentinels)/2+1),那么它将成为领导者。
- 如果此过程没有选举出领导者,将进入下一次选举。
领导者选举示例:
- s1 最先完成了客观下线,它会向 s2 和 s3 发送sentinel is-master-down-by-addr命令,s2 和 s3 同意选其为领导者。
- s1此时已经拿到2张投票,满足了大于等于max(quorum,num(sentinels)/2+1)=2 的条件,所以此时 s1 成为领导者。
注意
由于每个Sentinel节点只有一票,所以当 s2 向 s1 和 s3 索要投票时,只能获取一票;
而 s3 由于最后完成主观下线,当 s3 向 s1 和 s2 索要投票时一票都得不到。
在3个Sentinel节点上执行monitor命令:
- 可以看到sentinel is-master-down-by-addr命令,此命令的执行过程并 没有在Redis的日志中有所体现,monitor监控类似如下命令:
// 因为最后参数是"*",所以此时是Sentinel节点之间交换对主节点的失败判定
[0 127.0.0.1:38440] "SENTINEL" "is-master-down-by-addr" "127.0.0.1" "6379" "0" "*"
// 因为最后参数是具体的runid,所以此时代表runid="2f4430bb62c039fb125c5771d7cde2571a7
a5ab4"的节点希望目标Sentinel节点同意自己成为领导者。
[0 127.0.0.1:38440] "SENTINEL" "is-master-down-by-addr" "127.0.0.1" "6379" "1"
"2f4430bb62c039fb125c5771d7cde2571a7a5ab4"
- 选举的过程非常快,基本上谁先完成客观下线,谁就是领导者。
- 一旦Sentinel得到足够的票数,后面的选举过程。
故障转移
领导者选举出的Sentinel节点负责故障转移,具体步骤如下:
- 在从节点列表中选出一个节点作为新的主节点,选择方法如下:
- 过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节点ping响应、与主节点失联超过down-after-milliseconds*10秒。
- 选择slave-priority(从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
- 选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续。
- 选择runid最小的从节点。
- Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。
- Sentinel领导者节点会向剩余的从节点发送命令,让它们成为新主节 点的从节点,复制规则和parallel-syncs参数有关。
- Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点