likes
comments
collection
share

Redis 攻略面经(五)-- 详解哨兵机制

作者站长头像
站长
· 阅读数 15

📣 大家好,我是Zhan,一名个人练习时长一年半的大二后台练习生🏀

📣 这篇文章是复习 Redis 哨兵机制 的学习笔记📙

📣 如果有不对的地方,欢迎各位指正🙏🏼

📣 与君同舟渡,达岸各自归🌊


👉引言

根据我们上篇讲的主从复制中的同步数据,slave节点宕机恢复后可以找master节点同步数据,那master节点宕机怎么办?

Redis 在 2.8 版本以后提供的哨兵(Sentinel)机制,它的作用是实现主从节点故障转移,具体来说有三个作用:

  • 监控:哨兵会不断的检查masterslave是否按照预期工作
  • 自动故障恢复:如果master故障了,就选取一个slave来“当老大”,即使故障修复了也不会换回来。
  • 通知:在选出新的master后,需要让其他的slave客户端与新的master通信,那么就需要哨兵在执行故障转移的时候,通知其他的slave客户端
  • 上述三个功能如何实现,又有哪些细则,我们今天一起来学习学习~

Redis 攻略面经(五)-- 详解哨兵机制


⚙ 工作方式

⚠ 判断主节点故障

哨兵每隔一秒就会给所有的主从结点发送一个心跳检测的PING命令,当主从结点接受到PING命令后,会响应给哨兵一条命令,这样就能判断结点的工作状况,根据结点的工作情况,哨兵集群会做出不同的选择:

  1. 主观下线:如果主从结点没有在规定的时间内响应来自哨兵发送的PING,那么哨兵就会标注该结点为主观下线
  2. 客观下线:客观下线只针对于主节点,由于主节点不一定是因为宕机导致没有在规定的时间内响应,有可能是系统压力太大或者网络堵塞导致没有在规定的时间响应,因此为了减少误差,一般哨兵以集群的方式存在,具体的工作方式为:
    1. 如果有一个哨兵认为是主观下线,就会开始在集群中“投票”
    2. 当哨兵集群中赞同是主观下线的哨兵数唱过我们配置的quorum,就会标记这个结点为客观下线

Redis 攻略面经(五)-- 详解哨兵机制


👮🏼‍♂️ 选取哨兵 Leader

上面我们提到,为了减小误差,哨兵一般以集群的方式存在,而主从故障转移只需要一个哨兵,应该选哪个哨兵呢?

哨兵要成为Leader去进行主从故障转移,首先要成为Leader候选人:我们在上面在讲客观下线的时候有提到,会由一个哨兵发起投票,如果最后该哨兵收集到的赞同票 > quorum,这个哨兵就标记这个结点为客观下线,同时自身成为Leader候选人

Leader候选人要成为Leader又要投票(ps:要我说,这Redis就是喜欢投票/doge):

  • 所有的哨兵都会参与投票,但是只有一票
  • 除了候选人,都不能弃票和投自己
  • 最后,当选Leader的条件为:拿到一半以上的赞成票,并且票数大于等于quorum的将会成为Leader

我们在这里举两个例子来说明一下这个投票的可行性,也就是是否能标记结点为客观下线进行主从故障转移

  1. 五个哨兵、quorum=3、2个哨兵故障:
    1. 客观下线:此时集群中还剩3个哨兵,因此在一个哨兵判定主节点主观下线后进行投票,是有可能凑齐3票的,这就达到了quorum的值,因此可以判断主节点客观下线
    2. 主从故障转移:对于Leader的选举,需要拿到一半以上的票,也就是至少3票,而大于等于quorum,也是大于等于3,结合情况我们可以发现,其实是如果全票投一个结点,是能进行主从故障转移的
  2. 五个哨兵、quorum = 2、3个哨兵故障
    1. 客观下线:此时集群中还剩2个哨兵,也就是说是能达到quorum的值,即能够判定一个结点客观下线
    2. 主从故障转移:由于要拿到一半以上的票,也就是3票,但是只有两个哨兵,因此不能选出Leader
    3. 也就是说,虽然能够找到判定结点客观下线,却做不到主从故障转移,这就有一种前面判定客观下线的操作是无用功的感觉
  3. 因此,quorum 的值最好为 哨兵个数/2 + 1,且哨兵结点的数量最好是奇数个

选出了哨兵中的Leader,接下来就要正式开始主从故障转移操作了,总共有以下四步:

  1. 从所有从节点里面选出一个新的 Master 结点
  2. 通知其他从节点:后续的数据复制去找这个新选出来的主节点
  3. 通知客户端:把新主节点的IP和信息传给客户端,后续客户端就与这个新主节点通信
  4. 继续监视旧的主节点,在旧主节点重连之后,把它设置为从节点

🎯 选取新 Master 结点

故障转移的第一步就是选出一个状态良好、数据完整的从节点,然后向这个结点发送SLAVEOF no one,那么这个从节点就变为了主节点,但是如何判断这个结点状态良好、数据完整呢?我们分为以下几步:

🔨 初筛

我们首先要把网络状态不好的从节点给过滤掉:

  • Redis中有一个属性down-after-milliseconds * 10,表示主从结点断连的最大连接超时时间
  • 也就是说如果响应时间超过了我们指定的时间,它就会被认定为断连
  • 断连超过了10次,我们就认为这个从结点的网络状态不好
  • 以此筛掉所有网络状态不好的从节点

⛏ 优先级

每个Redis结点的配置文件都不同,这个我们在部署集群的时候应该有所了解,在Redis的配置文件中,我们可以给结点配置slave-priority,来表示该结点的优先级。

对于优先级高的,Redis优先选择它成为新的主节点,因此我们可以把一些内存更大、性能更好的Redis结点的优先级设置的高一些。


⚒ 数据量

如果优先级一样,我们就会比较数据量:每个从节点都会与主节点进行数据的通信,在讲解主从复制的数据传输的时候我们有提到这个缓冲区:repl_backlog_buffer,也就是那个环形缓冲区:

Redis 攻略面经(五)-- 详解哨兵机制

在进行增量同步的时候就使用到了它,当时我们有提到offset这个字段,也就是数据的偏移量,Redis会优先选择offset最接近master的offset的结点,也就是说选定复制的数据最多的那个结点。


🛠 ID 号

如果优先级一样、复制的进度也一样,就会选定ID号小的那个作为新的主结点,集群中的每个结点都有属于自己的ID号。


至此,便选出了新的 Master 结点,然后哨兵会向这个结点发送SLAVEOF no one,这个从节点便变成了新的主节点。


📢 通知从节点

选出了新的主节点后,哨兵下一步要做的就是让其他的从节点指向新的主节点,具体实现是靠着SLAVEOF命令

哨兵会给其他所有的从节点发送命令:SLAVEOF <新主节点的ip> <新主节点的port>

📣 通知客户端

接下来就需要通知客户端客户的主节点已经更换了,减少脑裂现象导致的数据丢失

通知客户端是通过Redis 的 发布者/订阅者 机制实现的,每个哨兵结点都提供这个机制,客户端可以订阅哨兵的消息,这里我们列举一些常见的频道:

频道说明
+sdown实例进入“主观下线”状态
-sdown实例退出“主观下线”状态
+odown实例进入“客观下线”状态
-odown实例退出“客观下线”状态
+slave-reconf-sent哨兵发送SLAVEOF命令,重新配置从库
+slave-reconf-inprog从库配置了新主库,但是还没有进行数据同步
+slave-reconf-done从库配置了新主库,不过数据同步结束了
+switch-master主库的地址发生改变

在这里,就是在+switch-master频道,发送了新的主节点的IP和端口的信息,然后客户端就会收取到这条消息,并使用新的主节点进行通信。


🎭 原主节点 -> 从节点

尽管原主节点可能宕机了,但是也要监视它,在它重新上线的时候,给他发送SLAVEOF <新主节点的ip> <新主节点的port> 的命令,让它也称为新主节点的从节点。

至此,整个主从结点的故障转移的工作结束!the end~


🎎 哨兵集群

哨兵集群是如何组成的呢,或者说哨兵之间如何通信的呢?

其实哨兵集群的搭建也依赖到了Redis 的 订阅者/发布者 机制,在集群中,有一个叫做_sentinel__:hello的频道,用于哨兵之间的相互通信。

例如:哨兵A把自己的IP和端口发布到这个频道上,那么哨兵B和哨兵C接受到信息后,就能根据获得的端口号和IP建立与哨兵A的网络连接:

Redis 攻略面经(五)-- 详解哨兵机制

哨兵是如何获取获取从节点的信息的呢?

哨兵可以通过主节点的连接,给主节点发送命令:INFO,这样就能拿到从节点列表,然后根据从节点列表的信息,和每个从节点建立连接,并持续的对从接地进行监控:

Redis 攻略面经(五)-- 详解哨兵机制


💬 总结

本文讲了Redis哨兵机制:从主节点故障开始,到新的主节点正常使用,这整个流程,我们在本文中详细讲解了,在文末我们也提到了Redis哨兵集群的组成:

  • 对于哨兵的工作机制,我们分别介绍了:
    • 在判断主节点故障时的主观下线客观下线
    • 选取哨兵Leader时的投票方式
    • 选用新的Master结点的评判标准
    • 把新主节点信息通知从节点的命令
    • 使用发布者/订阅者 机制进行与客户端的通信
    • 监听原主节点
  • 对于哨兵集群,我们以两个问题分别解释了:
    • 哨兵之间的通信机制
    • 哨兵与从节点之间的通信方式 相信读完今天的文章,大家能对Redis 的哨兵机制有了更深一步的理解~

🍁 友链


✒写在最后

都看到这里啦~,给个点赞再走呗~,也欢迎各位大佬指正以及补充,在评论区一起交流,共同进步!也欢迎加微信一起交流:Goldfish7710。咱们明天见~

Redis 攻略面经(五)-- 详解哨兵机制