一、Sentinel的三个定时任务:
-
每隔10秒,每个Sentinel节点向每个主节点或者从节点发送
info
命令,去获取最新的拓扑结构。
这也是在配置Sentinel节点时,只配置了Sentinel监控的主节点,但是却可以获取到主节点的从节点的原因。 -
每隔2秒,每个Sentinel节点向
_sentinel_:hello
频道发送对主节点的判断以及自身的信息。
每个Sentinel节点都会订阅_sentinel_:hello
频道,以此来了解其他Sentinel节点,同时交换对各个节点统计的信息,作为后面判定主节点客观下线以及选举Sentinel领导者的依据。 -
每隔1秒,每个Sentinel节点向所有其他节点发送
PING
命令进行心跳检测。该任务的执行是节点下线的判断数据来源。
二、主观下线与客观下线:
主观下线:
当某个Sentinel发送PING命令后,未在指定时间收到回应,则会把该节点标记为主观下线状态。
客观下线:
接着上面,如果被判定为主观下线的是一个主节点,那么该Sentinel向其他Sentinel发送sentinel is-master-down-by-addr
命令,询问其他节点的判断,若quonum数量的都同意,则当前Sentinel将主节点标记为客观下线。然后再次向各个Sentinel发送sentinel is-master-down-by-addr
命令,请求将自己投票为Sentinel领导者,去做故障转移工作。
(quonum表示主节点被判定为客观下线,需要进行同意的Sentinel节点数。在Sentinel结点配置文件中指定Sentinel监控的主节点时指定: sentinel monitor [主库别名] [主库ip:端口] [主库被判客观下线需要同意的sentinel结点数]
.)
sentinel is-master-down-by-addr
命令是做主节点下线判断还是选举Sentinel领导者,是由后面的runId参数决定的。
runId为 * 时,做下线判断;
runId为发送命令的Sentinel的runId时,表示当前Sentinel结点希望其他Sentinel为自己投票。
三、Sentinel领导者选举:
因为可能同时又多个Sentinel发现主节点下线,然后都发起投票。所以某个Sentinel结点收到命令后,如果还未进行投票,则进行投票。当某个Sentinel获取的票数大于等于max(quonum,Sentinel个数/2+1)时,该Sentinel称为领导者,去做后面的故障转移操作。
备注:选举使用的是Raft算法,上面过程只是一个简要概括。
四、故障转移:
Sentinel领导者执行故障转移操作:
- 选举出新的从节点
- 过滤:过滤出不健康的从节点,即已经主观下线、发送PING5秒内未回复、与主节点失联。
- 选择复制最完整的从节点,即复制偏移量那个最大的,若存在则选定该节点,不存在就选择runId最小的从节点。
- 让选举出的从节点执行
salveof no one
,晋升为主节点。 - 向其他从节点发送命令,让他们成为新的主节点的从节点。
- 关注之前客观下线的主节点,恢复后,让其也成为新的主节点的从节点。
总结:
可以看到,针对主从复制的缺点,Sentinel模式可以实现主节点宕机后的通知、自动化故障转移、客户端无需改动。
但是对于主节点的写压力与存储压力,Sentinel并没有办法解决,这部分工作由Redis Cluster来实现。