参考:
https://time.geekbang.org/column/article/274483
引言
如果主库挂了,我们就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库。这就涉及到三个问题:
- 主库真的挂了吗?(监控)
- 该选择哪个从库作为主库?(选主)
- 怎么把新主库的相关信息通知给从库和客户端呢?(通知)
在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的这三个问题
哨兵机制的基本流程
哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行。
哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。
- 监控主库运行状态,并判断主库是否客观下线;
- 在主库客观下线后,选取新主库;
- 选出新主库后,通知从库和客户端。
主观下线和客观下线(监控)
哨兵进程会使用 PING 命令检测它自己和主、从库的网络连接情况,用来判断实例的状态。
- 如果检测的是从库,那么,哨兵简单地把它标记为“主观下线”就行了
- 但是,如果检测的是主库,那么,哨兵还不能简单地把它标记为“主观下线”,开启主从切换。
因为很有可能存在这么一个情况:那就是哨兵误判了。一旦启动了主从切换,后续的选主和通知操作都会带来额外的计算和通信开销。
误判发生的情况?
误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下。
如何减少误判?
引入多个哨兵实例一起来判断,通常会采用多实例组成的集群模式进行部署,这也被称为哨兵集群。
只有大多数的哨兵实例,都判断主库已经“主观下线”了,主库才会被标记为“客观下线”。
如何选定新主库?(选主)
哨兵选择新主库的过程称为“筛选 + 打分”。
- 我们在多个从库中,先按照一定的筛选条件,把不符合条件的从库去掉。
- 然后,我们再按照一定的规则,给剩下的从库逐个打分,将得分最高的从库选为新主库
筛选
除了要检查从库的当前在线状态,还要判断它之前的网络连接状态。
具体如何判断之前的网络状态?
使用配置项 down-after-milliseconds * 10。其中,down-after-milliseconds 是我们认定主从库断连的最大连接超时时间。
打分
- 从库优先级
- 从库复制进度
- 从库 ID 号
第一轮:优先级最高的从库得分高。
用户可以通过 slave-priority 配置项,给不同的从库设置不同优先级。
第二轮:和旧主库同步程度最接近的从库得分高。
如果选择和旧主库同步最接近的那个从库作为主库
如何判断从库和旧主库间的同步进度呢?
主库会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置,而从库会用 slave_repl_offset 这个值记录当前的复制进度。
值最接近的,评分最高。
第三轮:ID 号小的从库得分高。
在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库。
我们再回顾下这个流程。首先,哨兵会按照在线状态、网络状态,筛选过滤掉一部分不符合要求的从库,然后,依次按照优先级、复制进度、ID 号大小再对剩余的从库进行打分,只要有得分最高的从库出现,就把它选为新主库。