Redis 的主库挂了,如何不间断服务?( 三 )


好了,这样我们就过滤掉了不适合做主库的从库,完成了筛选工作 。
接下来就要给剩余的从库打分了 。我们可以分别按照三个规则依次进行三轮打分 , 这三个规则分别是从库优先级、从库复制进度以及从库 ID 号 。只要在某一轮中,有从库得分最高,那么它就是主库了,选主过程到此结束 。如果没有出现得分最高的从库,那么就继续进行下一轮 。
第一轮:优先级最高的从库得分高 。
用户可以通过 slave-priority 配置项,给不同的从库设置不同优先级 。比如,你有两个从库,它们的内存大小不一样,你可以手动给内存大的实例设置一个高优先级 。在选主时 , 哨兵会给优先级高的从库打高分,如果有一个从库优先级最高,那么它就是新主库了 。如果从库的优先级都一样,那么哨兵开始第二轮打分 。
第二轮:和旧主库同步程度最接近的从库得分高 。
这个规则的依据是 , 如果选择和旧主库同步最接近的那个从库作为主库 , 那么 , 这个新主库上就有最新的数据 。
如何判断从库和旧主库间的同步进度呢?
上节课我向你介绍过 , 主从库同步时有个命令传播的过程 。在这个过程中,主库会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置,而从库会用 slave_repl_offset 这个值记录当前的复制进度 。
此时,我们想要找的从库 , 它的 slave_repl_offset 需要最接近 master_repl_offset 。如果在所有从库中,有从库的 slave_repl_offset 最接近 master_repl_offset,那么它的得分就最高,可以作为新主库 。
就像下图所示,旧主库的 master_repl_offset 是 1000 , 从库 1、2 和 3 的 slave_repl_offset 分别是 950、990 和 900,那么 , 从库 2 就应该被选为新主库 。

Redis 的主库挂了,如何不间断服务?

文章插图
基于复制进度的新主库选主原则
当然,如果有两个从库的 slave_repl_offset 值大小是一样的(例如,从库 1 和从库 2 的 slave_repl_offset 值都是 990),我们就需要给它们进行第三轮打分了 。
第三轮:ID 号小的从库得分高 。
每个实例都会有一个 ID,这个 ID 就类似于这里的从库的编号 。目前,Redis 在选主库时,有一个默认的规定:在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库 。
到这里,新主库就被选出来了,“选主”这个过程就完成了 。
我们再回顾下这个流程 。首先,哨兵会按照在线状态、网络状态,筛选过滤掉一部分不符合要求的从库,然后,依次按照优先级、复制进度、ID 号大小再对剩余的从库进行打分,只要有得分最高的从库出现 , 就把它选为新主库 。
小结我们已经一起探讨了哨兵机制,这是确保 Redis 提供持续服务的关键要素 。具体来说,主从数据库的数据同步是数据可靠性的基石 。在主数据库发生故障时,自动执行的主从切换是服务不中断的重要支持 。
Redis 的哨兵机制自动执行以下三项重要功能,实现了主从切换,从而降低了 Redis 集群的维护成本:
  1. 监测主库运行状态:监测主库的运行状态,以确定主库是否客观下线,即无法提供有效服务 。
  2. 选择新主库:一旦主库被客观下线,哨兵机制会选择一个新的主库 , 以维护集群的可用性 。
  3. 通知从库和客户端:选定新主库后 , 哨兵会通知相关从库切换到新的主库,以确保数据同步 。同时,客户端也会被重定向到新的主库 , 以继续访问数据 。
为了减少误判,通常使用多个哨兵实例进行部署,它们依据“多数原则”来判断主库的客观下线情况 。通常情况下 , 三个哨兵实例足以支持,只需两个哨兵认定主库已客观下线,切换过程将开始 。当需要更高的判断准确性时,可以考虑增加哨兵的数量,例如五个哨兵 。
然而,通过多个哨兵实例来减少误判可能引入新的挑战: