我们都了解redis主从模式 。在这个模式下,如果从库发生故障了,客户端可以继续向主库或其他从库发送请求,进行相关的操作,但是如果主库发生故障了,那就直接会影响到从库的同步,因为从库没有相应的主库可以进行数据复制操作了 。
而且,如果客户端发送的都是读操作请求,那还可以由从库继续提供服务,这在纯读的业务场景下还能被接受 。但是,一旦有写操作请求了,按照主从库模式下的读写分离要求,需要由主库来完成写操作 。此时,也没有实例可以来服务客户端的写操作请求了,如下图所示:

文章插图
无论是写服务中断,还是从库无法进行数据同步,都是不能接受的 。所以,如果主库挂了,我们就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库 。这就涉及到三个问题:
- 主库真的挂了吗?
- 该选择哪个从库作为主库?
- 怎么把新主库的相关信息通知给从库和客户端呢?
哨兵机制的基本流程
哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行 。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知 。
我们先看监控 。监控是指哨兵进程在运行时,周期性地给所有的主从库发送 PING 命令,检测它们是否仍然在线运行 。如果从库没有在规定时间内响应哨兵的 PING 命令,哨兵就会把它标记为“下线状态”;同样,如果主库也没有在规定时间内响应哨兵的 PING 命令,哨兵就会判定主库下线,然后开始自动切换主库的流程 。
这个流程首先是执行哨兵的第二个任务,选主 。主库挂了以后,哨兵就需要从很多个从库里,按照一定的规则选择一个从库实例,把它作为新的主库 。这一步完成后,现在的集群里就有了新主库 。
然后,哨兵会执行最后一个任务:通知 。在执行通知任务时,哨兵会把新主库的连接信息发给其他从库,让它们执行 replicaof 命令,和新主库建立连接,并进行数据复制 。同时,哨兵会把新主库的连接信息通知给客户端,让它们把请求操作发到新主库上 。
我画了一张图片,展示了这三个任务以及它们各自的目标 。

文章插图
在这三个任务中,通知任务相对来说比较简单,哨兵只需要把新主库信息发给从库和客户端,让它们和新主库建立连接就行,并不涉及决策的逻辑 。但是,在监控和选主这两个任务中,哨兵需要做出两个决策:
- 在监控任务中,哨兵需要判断主库是否处于下线状态;
- 在选主任务中,哨兵也要决定选择哪个从库实例作为主库 。
你首先要知道的是,哨兵对主库的下线判断有“主观下线”和“客观下线”两种 。那么,为什么会存在两种判断呢?它们的区别和联系是什么呢?
主观下线和客观下线
哨兵进程会使用 PING 命令检测它自己和主、从库的网络连接情况,用来判断实例的状态 。如果哨兵发现主库或从库对 PING 命令的响应超时了,那么,哨兵就会先把它标记为“主观下线” 。
如果检测的是从库,那么,哨兵简单地把它标记为“主观下线”就行了,因为从库的下线影响一般不太大,集群的对外服务不会间断 。
但是,如果检测的是主库,那么,哨兵还不能简单地把它标记为“主观下线”,开启主从切换 。因为很有可能存在这么一个情况:那就是哨兵误判了,其实主库并没有故障 。可是,一旦启动了主从切换,后续的选主和通知操作都会带来额外的计算和通信开销 。
【哨兵机制:主库挂了,如何不间断服务?】为了避免这些不必要的开销,我们要特别注意误判的情况 。
首先,我们要知道啥叫误判 。很简单,就是主库实际并没有下线,但是哨兵误以为它下线了 。误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下 。
一旦哨兵判断主库下线了,就会开始选择新主库,并让从库和新主库进行数据同步,这个过程本身就会有开销,例如,哨兵要花时间选出新主库,从库也需要花时间和新主库同步 。而在误判的情况下,主库本身根本就不需要进行切换的,所以这个过程的开销是没有价值的 。正因为这样,我们需要判断是否有误判,以及减少误判 。
推荐阅读
- Linux select/poll机制原理分析
- 机制针形名优茶工艺,西湖龙井等名优茶机制率达95%
- 防御sqlmap攻击之动态代码防御机制
- 什么是Java可变参数列表?怎么和重载机制配合使用?
- Linux分段系统中的地址映射和基本机制
- 什么是“内存管理机制”?
- WebSocket心跳检测和重连机制
- 如何利用自媒体平台的「推荐机制」,写出叫好又叫座的爆文来?
- MySQL-锁机制详述
- C语言的编译机制:分制原则与三种文件
