当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,以往这个过程需要人工手动来操作。Redis 2.8
中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。
哨兵的作用就是监控 Redis
系统的运行状况。它的功能包括以下两个:
-
监控主服务器和从服务器是否正常运行。
-
主服务器出现故障时自动将从服务器转换为主服务器。
- 每个
sentinel
(哨兵)进程以每秒钟一次的频率向集群中的master
主服务器,slave
从服务器以及其他sentinel
进程发送一个PING
命令 - 如果一个实例距离最后一次有效回复
PING
命令的时间超过配置的时长, 则这个实例会被哨兵进程标记为主观下线SDOWN
- 如果主观下线的是
slave
或者sentinel
,则没有后续的操作
- 如果主观下线的是
- 主观下线的节点为主节点时,该
sentinel
节点可以通过命令sentinel is_master_down_by_addr
来获得其他sentinel
对于该主节点的判断- 当有超过
QUORUM
(配置文件里的,默认半数)个sentinel
判定主观下线时,master
会被标记为客观下线ODOWN
- 在一般情况下,每个
sentinel
进程会以每10
秒一次的频率向集群中的所有master
、slave
从服务器发送INFO
命令
- 当有超过
- 若没有足够数量的
sentinel
同意master
下线,master
的客观下线状态就会被移除,恢复正常状态。 - 若
master
重新向sentinel
的PING
命令返回有效回复,master
的主观下线状态就会被移除,变为新的从节点。
当 sentinel
对于 master
已经做了客观下线,并不是马上就可以开始故障转移,而是先从 sentinel
中选举出一个领导者,让领导者去完成故障转移的工作。
- 每个
sentinel
都有资格成为领导者,当它确认主节点主观下线时,会向其他sentinel
发送sentinel is-master-down-by-addr
命令,要求竞选。每个sentinel
都会发投票请求 - 投票:
sentinel
节点,如果没投过票,将同意该请求,否则拒绝(先到先被投) - 如果某个
sentinel
节点发现自己的票数已经大于等于max(QUORUM, num(sentinels)/2+1 半数+176)
,那么它将成为领导者 - 如果此过程没有选举出领导者,将进入下一次选举。
领头 sentinel
会将已下线 master
的所有从服务器保存在一个列表中,按照规则进行挑选。
- 排除所有下线、没有回复
INFO
命令、与master
断开超过一定时长的从节点 - 按照
slave
复制偏移量,选出其中偏移量最大的slave
。如果有多个优先级一样的的slave
,则选取run id
最小的。 - 选出新的
master
之后,领头sentinel
会以每秒一次的频率向新的master
发送SLAVEOF no one
命令,当得到确切的回复role
由slave
变为master
之后,当前服务器顺利升级为master
服务器。 - 领头
sentinel
向其他从节点发送SLAVEOF
命令,让其他服务器跟踪这个新的主节点。 - 领头
sentinel
会将原来的主节点更新为从节点,并保持对其关注,当其恢复后命令它去复制新的主节点。
- 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。(从节点分摊读压力等)
- 主从可以自动切换,系统更健壮,可用性更高。
- 没法扩容(扩容场景用 Cluster)
sentiel
和 cluster
的主节点选取,参考了 raft
协议(是否就是 raft
协议,存疑。有的说是,但实现细节上是有不同的)
至于主从同步、数据一致性,则完全没有使用 raft
协议。raft
要求主节点收到命令后,至少同步给一定的从节点后,才视为成功返回结果。而 redis
是全异步的,主节点写成功就视为成功。
redislab
有个 redis
的插件,以插件的形式,专门使用 raft
实现了分布式一致。