哨兵紧张卖力做三件事:
①监控,监控主、从节点是否正常运行
②选主,Sentinel集群须要选择一个Leader来进行主从切换。

③关照,选主完成后,须要把新主库的连接信息关照给从库和客户端。
1.状态感知
哨兵启动后只指定了master的地址,要想知道全体集群中完全的拓扑关系怎么做呢?
哨兵每隔10秒会向每个master节点发送 info 命令, info 命令返回的信息中,包含了主从拓扑关系,个中包括每个slave的地址和端口号。有了这些信息后,哨兵就会记住这些节点的拓扑信息,在后续发生故障时,选择得当的slave节点进行故障规复。
那么有小伙伴会问,哨兵之间是如何通信的呢?
基于Redis供应的发布(pub)/订阅(sub)机制完成的。哨兵节点不会直接与其他哨兵节点建立连接, 而是首先会和主库建立起连接 ,然后向一个名为" sentinel :hello"频道发送自己的信息(IP 和端口),其他订阅了该频道的哨兵节点就会获取到该哨兵节点信息,从而哨兵节点之间互知。
2.心跳检测每一秒,每个 Sentinel 对 Master、Slave、其他哨兵节点实行PING命令,检测它们是否仍旧在线运行,如果有节点在规定韶光内没有相应PING命令,那么该哨兵节点认为此节点"主不雅观下线"。
3.主不雅观下线和客不雅观下线为什么须要客不雅观下线机制?
由于当前哨兵节点探测对方没有得到相应,很有可能这两个机器之间的网络发生了故障,而 Master 节点本身没有任何问题,此时就认为 Master 故障是禁绝确的。
为理解决上述问题,客不雅观下线应运而生,Sentinel一样平常汇合群支配,引入多个哨兵实例一起来判断,就可以避免单个哨兵由于自身网络状况不好,而误判主库下线的情形。
假设我们有N个哨兵实例,如果有N/2+1个实例判断主库“主不雅观下线”,此时把节点标记为“客不雅观下线”,此时就可以做主从切换了。
4.选举哨兵领导者?假设Sentinel 判断主库“主不雅观下线”后,就会给其他 Sentinel 实例发送 is-master-down-by-addr 命令,接着,其他 Sentinel 实例会根据自己和主库的连接情形,做出附和和反对决定。
假设我们有N个哨兵实例,如果有#{quorum}个实例附和,此时这个 Sentinel 就会给其他 Sentinel 发送主从切换要求,其他 Sentinel 会进行投票,如果投票通过,这个 Sentinel 就可以进行主从切换了, 这个投票过程被称为Leader 选举 。实在整体思想和Zookeeper一样的。
在投票过程中,任何一个想成为 Leader 的哨兵,要知足两个条件:第一,拿到半数以上的附和票;第二,拿到的票数同时还须要大于即是哨兵配置文件中的 quorum 值。
quorum一样平常我们都会配置成 实例数量/2+1
此时会有小伙伴问,如果所有Sentinel都想成为Leader实行主从切换怎么办?
哨兵选举领导者的过程类似于Raft算法,每个哨兵都设置一个 随机超时时间 ,超时后向其他哨兵发送申请成为领导者的要求,把超时时间都分散开来, 在大多数情形下只有一个做事器节点先发起选举,而不是同时发起选举,这样就能减少因选票瓜分导致选举失落败的情形 。
后期我会专门写一个专栏为大家先容所有同等性算法,例如:Paxos、Raft、Gossip、ZAB等,到时候详细给大家讲解Sentinel是如何办理上述问题的。
5.谁来做新的Master?选择新master过程也是有优先级的,在多个slave的场景下,优先级按照:slave-priority配置 > 数据完全性 > runid较小者进行选择。
用户可以通过 slave-priority 配置项,给不同的从库设置不同优先级。如果所有从节点的 slave-priority 值同等,那就看谁的数据更完全。
如何判断谁的数据更完全呢?
主库会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置,而从库会用 slave_repl_offset 这个值记录当前的复制进度。此时,哪个从库的 slave_repl_offset 最靠近 master_repl_offset。那么谁就可以作为新主库。
如果 slave_repl_offset都同等,那就比 runid,选择runid最小的 Slave 节点作为新主库。
选择出新主库,哨兵 Leader 会给该节点发送 slaveof no one 命令,让该节点成为 Master。之后,哨兵 Leader会给故障节点的所有 Slave 发送 slaveof $newmaster 命令,让这些 Slave 成为新 Master 的从节点,开始重新的Master 上同步数据(这里会进行全量复制)。末了哨兵 Leader 把故障节点降级为 Slave,并写入到自己的配置文件中,待这个故障节点规复后,则自动成为新 Master 节点的 Slave。至此,全体故障切换完成。
6.如何关照客户端?上面已经先容了完全的故障切换全流程,故障切换后,主节点变革了,客户端如何感知呢?
基于Redis供应的发布(pub)/订阅(sub)机制完成的,客户端可以从哨兵订阅,故障转移后,客户端会收到订阅。
原文链接:https://juejin.cn/post/6995008999875674120