- 引言
- 哨兵机制的基本流程
- 主观下线和客观下线
- 如何选定新主库
如果主库发生故障了,那就直接会影响到从库的同步,因为从库没有相应的主库可以进行数据复制 *** 作了。
如果客户端发送的都是读 *** 作请求,那还可以由从库继续提供服务,这在纯读的业务场景下还能被接受。但是,一旦有写 *** 作请求了,按照主从库模式下的读写分离要求,需要由主库来完成写 *** 作。此时,也没有实例可以来服务客户端的写 *** 作请求了。
如果主库挂了,我们就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库。这就涉及到三个问题:
- 主库真的挂了吗?
- 该选择哪个从库作为主库?
- 怎么把新主库的相关信息通知给从库和客户端呢?
这就要提到哨兵机制了。在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制。
哨兵机制的基本流程哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。
- 监控:是指哨兵进程在运行时,周期性地给所有的主从库发送 PING 命令,检测它们是否仍然在线运行。
- 选主:主库挂了以后,哨兵就需要从很多个从库里,按照一定的规则选择一个从库实例,把它作为新的主库。
- 通知:执行通知任务时,哨兵会把新主库的连接信息发给其他从库,让它们执行replicaof命令,和新主库建立连接,并进行数据复制。同时,哨兵会把新主库的连接信息通知给客户端,让它们把请求 *** 作发到新主库上。
你首先要知道的是,哨兵对主库的下线判断有“主观下线”和“客观下线”两种。那么,为什么会存在两种判断呢?它们的区别和联系是什么呢?
哨兵进程会使用 PING 命令检测它自己和主、从库的网络连接情况,用来判断实例的状态。
如果检测的是从库,那么,哨兵简单地把它标记为“主观下线”就行了,但是,如果检测的是主库,那么,哨兵还不能简单地把它标记为“主观下线”,开启主从切换。因为很有可能存在这么一个情况:那就是哨兵误判了,其实主库并没有故障。
误判:就是主库实际并没有下线,但是哨兵误以为它下线了。误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下。
一旦哨兵判断主库下线了,就会开始选择新主库,并让从库和新主库进行数据同步,这个过程本身就会有开销,例如,哨兵要花时间选出新主库,从库也需要花时间和新主库同步。
哨兵机制通常会采用多实例组成的集群模式进行部署,这也被称为哨兵集群。引入多个哨兵实例一起来判断,就可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。
在判断主库是否下线时,不能由一个哨兵说了算,只有大多数的哨兵实例,都判断主库已经“主观下线”了,主库才会被标记为“客观下线”,这个叫法也是表明主库下线成为一个客观事实了。这个判断原则就是:少数服从多数。同时,这会进一步触发哨兵开始主从切换流程。
简单来说,“客观下线”的标准就是,当有 N 个哨兵实例时,最好要有 N/2 + 1 个实例判断主库为“主观下线”,才能最终判定主库为“客观下线”。
一般来说,我把哨兵选择新主库的过程称为“筛选 + 打分”。简单来说,我们在多个从库中,先按照一定的筛选条件,把不符合条件的从库去掉。然后,我们再按照一定的规则,给剩下的从库逐个打分,将得分最高的从库选为新主库。
一般情况下,我们肯定要先保证所选的从库仍然在线运行。不过,在选主时从库正常在线,这只能表示从库的现状良好,并不代表它就是最适合做主库的。设想一下,如果在选主时,一个从库正常运行,我们把它选为新主库开始使用了。可是,很快它的网络出了故障,此时,我们就得重新选主了。这显然不是我们期望的结果。
所以,在选主时,除了要检查从库的当前在线状态,还要判断它之前的网络连接状态。如果从库总是和主库断连,而且断连次数超出了一定的阈值,可以判断这个从库的网络状况并不是太好,就可以把这个从库筛掉了。
你使用配置项 down-after-milliseconds * 10。其中,down-aftermilliseconds是我们认定主从库断连的最大连接超时时间。如果在 down-aftermilliseconds毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从库的网络状况不好,不适合作为新主库。
接下来就要给剩余的从库打分了。我们可以分别按照三个规则依次进行三轮打分,这三个规则分别是从库优先级、从库复制进度以及从库 ID 号。只要在某一轮中,有从库得分最高,那么它就是主库了,选主过程到此结束。如果没有出现得分最高的从库,那么就继续进行下一轮。
-
第一轮:优先级最高的从库得分高。用户可以通过 slave-priority 配置项,给不同的从库设置不同优先级。如果从库的优先级都一样,那么哨兵开始第二轮打分。
-
第二轮:和旧主库同步程度最接近的从库得分高。如果选择和旧主库同步最接近的那个从库作为主库,这个新主库上就有最新的数据。在这个过程中,主库会用master_repl_offset 记录当前的最新写 *** 作在 repl_backlog_buffer 中的位置,而从库会用 slave_repl_offset 这个值记录当前的复制进度。如果在所有从库中,有从库的 slave_repl_offset 最接近 master_repl_offset,那么它的得分就最高,可以作为新主库。
-
第三轮:ID 号小的从库得分高。每个实例都会有一个 ID,这个 ID 就类似于这里的从库的编号。目前,Redis 在选主库时,有一个默认的规定:在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库。
觉得有用的客官可以点赞、关注下!感谢支持谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)