美文网首页redis
【redis】哨兵集群:哨兵挂了,主从库还能切换吗?

【redis】哨兵集群:哨兵挂了,主从库还能切换吗?

作者: Bogon | 来源:发表于2023-05-15 01:05 被阅读0次

    哨兵实例之间可以相互发现,要归功于Redis提供的pub/sub机制,也就是发布/订阅机制。

    只有订阅了同一个频道的应用,才能通过发布的消息进行信息交换。

    在主从集群中,主库上有一个名为“sentinel:hello”的频道,不同哨兵就是通过它来相互发现,实现互相通信的。

    59b5dffb283ba4104fd23b59caf0edc0_ca42698128aa4c8a374efbc575ea22b1.jpg

    那么,哨兵是如何知道从库的IP地址和端口的呢?
    这是由哨兵向主库发送INFO命令来完成的。

    2cbf33d1a258e93612c06f3559e32236_88fdc68eb94c44efbdf7357260091de0.jpg

    从本质上说,哨兵就是一个运行在特定模式下的Redis实例,只不过它并不服务请求操作,只是完成监控、选主和通知的任务。
    所以,每个哨兵实例也提供pub/sub机制,客户端可以从哨兵订阅消息。
    哨兵提供的消息订阅频道有很多,不同频道包含了主从库切换过程中的不同关键事件。

    频道有这么多,一下子全部学习容易丢失重点。
    我把重要的频道汇总在了一起,涉及几个关键事件,包括主库下线判断、新主库选定、从库重新配置。


    287248286bc69661fc52291812ba9928_4e9665694a9565abbce1a63cf111f725.jpg

    知道了这些频道之后,你就可以让客户端从哨兵这里订阅消息了。
    具体的操作步骤是,客户端读取哨兵的配置文件后,可以获得哨兵的地址和端口,和哨兵建立网络连接。然后,我们可以在客户端执行订阅命令,来获取不同的事件消息。

    由哪个哨兵执行主从切换?

    确定由哪个哨兵执行主从切换的过程,和主库“客观下线”的判断过程类似,也是一个“投票仲裁”的过程。

    在具体了解这个过程前,我们再来看下,判断“客观下线”的仲裁过程。

    哨兵集群要判定主库“客观下线”,需要有一定数量的实例都认为该主库已经“主观下线”了。
    我在上节课向你介绍了判断“客观下线”的原则,接下来,我介绍下具体的判断过程。

    任何一个实例只要自身判断主库“主观下线”后,就会给其他实例发送is-master-down-by-addr命令。
    接着,其他实例会根据自己和主库的连接情况,做出Y或N的响应,Y相当于赞成票,N相当于反对票。

    ead7967b8728e1c73ed87d45b1555921_e0832d432c14c98066a94e0ef86af384.jpg

    在投票过程中,任何一个想成为Leader的哨兵,要满足两个条件:
    第一,拿到半数以上的赞成票;
    第二,拿到的票数同时还需要大于等于哨兵配置文件中的quorum值。

    以3个哨兵为例,假设此时的quorum设置为2,那么,任何一个想成为Leader的哨兵只要拿到2张赞成票,就可以了。

    需要注意的是,如果哨兵集群只有2个实例,此时,一个哨兵要想成为Leader,必须获得2票,而不是1票。
    所以,如果有个哨兵挂掉了,那么,此时的集群是无法进行主从库切换的。
    因此,通常我们至少会配置3个哨兵实例。
    这一点很重要,你在实际应用时可不能忽略了。

    通常,我们在解决一个系统问题的时候,会引入一个新机制,或者设计一层新功能,就像我们在这两节课学习的内容:为了实现主从切换,我们引入了哨兵;
    为了避免单个哨兵故障后无法进行主从切换,以及为了减少误判率,又引入了哨兵集群;
    哨兵集群又需要有一些机制来支撑它的正常运行。

    再给你分享一个经验:要保证所有哨兵实例的配置是一致的,尤其是主观下线的判断值down-after-milliseconds。
    我们曾经就踩过一个“坑”。当时,在我们的项目中,因为这个值在不同的哨兵实例上配置不一致,导致哨兵集群一直没有对有故障的主库形成共识,也就没有及时切换主库,最终的结果就是集群服务不稳定。
    所以,你一定不要忽略这条看似简单的经验。

    假设有一个Redis集群,是“一主四从”,同时配置了包含5个哨兵实例的集群,quorum值设为2。在运行过程中,如果有3个哨兵实例都发生故障了,此时,Redis主库如果有故障,还能正确地判断主库“客观下线”吗?如果可以的话,还能进行主从库自动切换吗?此外,哨兵实例是不是越多越好呢,如果同时调大down-after-milliseconds值,对减少误判是不是也有好处呢?

    Redis 1主4从,5个哨兵,哨兵配置quorum为2,如果3个哨兵故障,当主库宕机时,哨兵能否判断主库“客观下线”?能否自动切换?

    经过实际测试,我的结论如下:

    1、哨兵集群可以判定主库“主观下线”。由于quorum=2,所以当一个哨兵判断主库“主观下线”后,询问另外一个哨兵后也会得到同样的结果,2个哨兵都判定“主观下线”,达到了quorum的值,因此,哨兵集群可以判定主库为“客观下线”。

    2、但哨兵不能完成主从切换。哨兵标记主库“客观下线后”,在选举“哨兵领导者”时,一个哨兵必须拿到超过多数的选票(5/2+1=3票)。但目前只有2个哨兵活着,无论怎么投票,一个哨兵最多只能拿到2票,永远无法达到多数选票的结果。

    但是投票选举过程的细节并不是大家认为的:每个哨兵各自1票,这个情况是不一定的。

    下面具体说一下:

    场景a:哨兵A先判定主库“主观下线”,然后马上询问哨兵B(注意,此时哨兵B只是被动接受询问,并没有去询问哨兵A,也就是它还没有进入判定“客观下线”的流程),哨兵B回复主库已“主观下线”,达到quorum=2后哨兵A此时可以判定主库“客观下线”。此时,哨兵A马上可以向其他哨兵发起成为“哨兵领导者”的投票,哨兵B收到投票请求后,由于自己还没有询问哨兵A进入判定“客观下线”的流程,所以哨兵B是可以给哨兵A投票确认的,这样哨兵A就已经拿到2票了。等稍后哨兵B也判定“主观下线”后想成为领导者时,因为它已经给别人投过票了,所以这一轮自己就不能再成为领导者了。

    场景b:哨兵A和哨兵B同时判定主库“主观下线”,然后同时询问对方后都得到可以“客观下线”的结论,此时它们各自给自己投上1票后,然后向其他哨兵发起投票请求,但是因为各自都给自己投过票了,因此各自都拒绝了对方的投票请求,这样2个哨兵各自持有1票。

    场景a是1个哨兵拿到2票,场景b是2个哨兵各自有1票,这2种情况都不满足大多数选票(3票)的结果,因此无法完成主从切换。

    经过测试发现,场景b发生的概率非常小,只有2个哨兵同时进入判定“主观下线”的流程时才可以发生。我测试几次后发现,都是复现的场景a。

    哨兵实例是不是越多越好?

    并不是,我们也看到了,哨兵在判定“主观下线”和选举“哨兵领导者”时,都需要和其他节点进行通信,交换信息,哨兵实例越多,通信的次数也就越多,而且部署多个哨兵时,会分布在不同机器上,节点越多带来的机器故障风险也会越大,这些问题都会影响到哨兵的通信和选举,出问题时也就意味着选举时间会变长,切换主从的时间变久。

    调大down-after-milliseconds值,对减少误判是不是有好处?

    是有好处的,适当调大down-after-milliseconds值,当哨兵与主库之间网络存在短时波动时,可以降低误判的概率。但是调大down-after-milliseconds值也意味着主从切换的时间会变长,对业务的影响时间越久,我们需要根据实际场景进行权衡,设置合理的阈值。

    参考

    哨兵机制:主库挂了,如何不间断服务?
    https://time.geekbang.org/column/article/274483

    Redis哨兵模式(sentinel)学习
    https://www.cnblogs.com/kevingrace/p/9004460.html

    相关文章

      网友评论

        本文标题:【redis】哨兵集群:哨兵挂了,主从库还能切换吗?

        本文链接:https://www.haomeiwen.com/subject/vcoysdtx.html