在学习过redis 的主从模式之后,我们可以思考一个问题 如果主库发生故障,则没有实例可以去服务客户端的写操作请求,这时候应该如何处理呢?
我们在这个时候,需要考虑这三个问题:
- 主库真的故障了吗?
- 如果主库故障,我们应该如何去选择从库作为主库?
- 我们如何把新的主库信息通知给从库和客户端呢?
Redis 的哨兵机制
实现主从库自动切换的关键机制,解决主从复制模式下故障转移的问题。
基本流程
哨兵主要负责的是 监控(防止主库出现故障),选择主库和通知新主库信息
- 监控是指哨兵进程在运行的时候,周期性的给所有主从库发送ping 命令,检测有没有在运行
- 如果从库没有相应ping 命令,哨兵则会标记为 “主库下线”,如果主库没有按时相应ping 命令,然后开始
自动切换主库
的流程。 - 哨兵需要在很多个从库中,按照一定的规则选择一个从库实例,作为新的主库,集群中就有了新主库
- 哨兵会把新主库的链接信息发给其他主库,让从库和新主库建立连接,并进行数据复制,同时,哨兵会把新主库的连接信息通知给客户单,发送请求操作到新的主库上。
监控和选主任务中涉及到决策:
- 监控任务中,哨兵如何判断主库是不是处于下线状态
- 在选主任务中,哨兵决定选择哪个从库作为主库
一般判断 主库的下线有两种方案,"主观下线"和 “客观下线”,接下来展开说一下这两种方案
主观下线
- 哨兵进程会使用 ping 命令去进行检测,根据网络状态判断,实例的状态。如果超时,哨兵就会暂时进行
标记
为主观下线 - 如果是从库,哨兵直接标记就可以,集群对外服务不间断。
- 这里我们需要处理
误判
的情况,因为有可能网络状态拥塞等原因导致哨兵误判,一旦开启了主从切换,后续的选主和通知操作都会带来额外的计算和通信开销。 - 我们可以通过
引入多个哨兵实例一起去进行判断
,可以在一定程度上减少误判率 - 判断主库有没有下线,主要是通过大多数的哨兵实例,判断主库已经 “主观下线” 了,主库才会被标记为"客观下线", 通过
少数服从多数
机制来出发哨兵开始主从切换流程。(一般是 N/2 + 1个实例判断
)
客观下线
- 当N/2 +1个实例判断主库为 " 主观下线" , 才能判断主库为 “客观下线”
如何选定新主库
- 我们通过一定筛选和一定的规则给剩下的从库逐个打分,将得分最高的从库选为新主库
- 选主的时候,需要检查从库的当前在线状态,还要判断它之前的网络状态,我们可以通过
down-after-milliseconds
去进行判断 - 我们通过
从库优先级,从库复制进度以及从库ID号
来对于从库进行打分,选出得分最高的。