为什么至少三个哨兵_Redis高手系列之哨兵挂了,主从库何去何从?

本文详细介绍了Redis哨兵系统的工作原理,包括哨兵如何通过pub/sub机制组建集群、如何监控主从库并进行切换,以及哨兵如何通知客户端。文章强调了哨兵集群至少需要三个实例以防止单点故障,并讨论了哨兵间的选举过程,确保在主库故障时能顺利完成主从切换。
摘要由CSDN通过智能技术生成

上篇文章我们了解到,主库挂了,有个神奇的东西--哨兵---来进行主从自动切换,为了提高准确率,Redis又引入了哨兵集群。但是如果倒霉,哨兵挂了,那该怎么办?

不要慌,既然是集群,总不会全挂掉,如果有哨兵实例挂了,其他哨兵的还能接着服务。

那么哨兵是如何组成一个集群的呢?

带着问题我们接着往下看。

如果各位部署过哨兵集群的话几句知道,在配置哨兵的信息时,我们只需要用到下面的这个配置项,设置主库的IP端口,并没有配置其他哨兵的连接信息。

sentinel monitor <master-name> <ip> <redis-port> <quorum>

既然每个哨兵都不知道彼此的地址,那他们是如何凑到一起的呢?

这个时候就不得不说Redis提供的pub/sub机制了。

1、基于pub/sub机制的哨兵集群组成

pub/sub机制也称为发布订阅机制。其实哨兵只要和主库建立了连接,就能知道其他的哨兵的ip和端口了。其实就是相当于主库做了一个中介,哨兵通过主库然后把自己的Ip和端口分享给其他的哨兵。

这里引入一个概念--频道,什么是频道呢?

大家可以这样理解,就是只有在同一个频道,我们才能相互通信,官方说频道就是消息的类别,这样说也很贴切,消息类别相同就是在同一个频道,就比如说二狗子在吃饭,问你吃不吃,然后你在蹲坑,问他蹲不蹲,这样一看就不在一个频道,这还交流个毛。

只有应用订阅了相同的一个频道他们才能友好の交流。

Redis在主从集群的主库上有这样的一个频道---__sentinel__:hello, 哨兵们就是通过他进行相互交流的。

我们先看张图理解下:

41d04da212871cff5572d5936377e2b6.png

额。。。不好意思不是这张图

32d4180c8c1b3d297a3cdc8286c6acc5.png

假设现在有三个哨兵,哨兵1把自己的ip和端口发布到了__sentinel__:hello这个频道上,然后哨兵2、3订阅了这个频道,就直接可以拿哨兵1的信息,然后与哨兵1建立连接。以此类推,哨兵2和哨兵3也相互建立连接。

相互连接以后,这就形成了集群,这个时候就可以履行他们的职责了,具体的职责我上篇文章也说了,这里就不重复了。

到这里不知道你发现没有,我们讲的是哨兵与主库建立连接,那从库呢?从库也要连接呀,小弟也有人权呀!!!

从库肯定也是要进行通信的,不然怎么进行主从切换呢?

那么,哨兵是如何知道从库的IP地址和端口的呢?

其实也不复杂,还是要依赖主库,只不过命令不一样了,哨兵向主库发一个INFO的命令,然后主库会把从库的信息返回给哨兵,这些信息里面就包括了从库的连接信息,然后哨兵就会和每个从库进行连接,并且进行实时的监控。

04ea0266d3fccd259ee5a60707aecfb9.png

到这里是不是就连接完了?别忘了,主从切换后,客户端怎么能知道呢?

所以哨兵还需要和客户端进行连接,需要把新主库的信息通知给客户端。

而且,在实际使用哨兵时,客户端如何通过监控了解哨兵进行主从切换的过程呢?比如说,主从切换进行到哪一步了?这其实就是要求,客户端能够获取到哨兵集群在监控、选主、切换这个过程中发生的各种事件。

此时,我们仍然可以依赖pub/sub机制,来帮助我们完成哨兵和客户端间的信息同步。

2、基于pub/sub机制的客户端事件通知

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

下面这些就是重要的频道,涉及几个关键事件:

6e0c666385d3c57feb7953f84df13dcf.png

有了这些频道,客户端就能从哨兵这里订阅消息了。

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

举个例子,你可以执行如下命令,来订阅“所有实例进入客观下线状态的事件”:

SUBSCRIBE +odown

当然,你也可以执行如下命令,订阅所有的事件:

PSUBSCRIBE  *

当哨兵把新主库选择出来后,客户端就会看到下面的switch-master事件。这个事件表示主库已经切换了,新主库的IP地址和端口信息已经有了。这个时候,客户端就可以用这里面的新主库地址和端口进行通信了。

switch-master <master name> <oldip> <oldport> <newip> <newport>

好了,有了pub/sub机制,哨兵和哨兵之间、哨兵和从库之间、哨兵和客户端之间就都能建立起连接了,再加上我们上节课介绍主库下线判断和选主依据,哨兵集群的监控、选主和通知三个任务就基本可以正常工作了。

到这里你以为结束了?那我再提个问题看看你是否知道:

主库故障以后,哨兵集群有多个实例,那怎么确定由哪个哨兵来进行实际的主从切换呢?

不知道吧,我们接着分析。

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

确定由哪个哨兵执行主从切换的过程,和主库“客观下线”的判断过程类似,也是一个“投票仲裁”的过程。在具体了解这个过程前,我们再来看下,判断“客观下线”的仲裁过程。

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

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

4b0b0168131c5af1edbaab99a27c97e8.png

一个哨兵获得了仲裁所需的赞成票数后,就可以标记主库为“客观下线”。这个所需的赞成票数是通过哨兵配置文件中的quorum配置项设定的。例如,现在有5个哨兵,quorum配置的是3,那么,一个哨兵需要3张赞成票,就可以标记主库为“客观下线”了。这3张赞成票包括哨兵自己的一张赞成票和另外两个哨兵的赞成票。

此时,这个哨兵就可以再给其他哨兵发送命令,表明希望由自己来执行主从切换,并让所有其他哨兵进行投票。这个投票过程称为“Leader选举”。因为最终执行主从切换的哨兵称为Leader,投票过程就是确定Leader。

在投票过程中,任何一个想成为Leader的哨兵,要满足两个条件:第一,拿到半数以上的赞成票;第二,拿到的票数同时还需要大于等于哨兵配置文件中的quorum值。以3个哨兵为例,假设此时的quorum设置为2,那么,任何一个想成为Leader的哨兵只要拿到2张赞成票,就可以了。

这么说你就理解了吧,什么?没理解?

那我再找张图,展示一下3个哨兵、quorum为2的选举过程。

65272865624d8f99c1ab99d74e293a01.png

在T1时刻,S1判断主库为“客观下线”,它想成为Leader,就先给自己投一张赞成票,然后分别向S2和S3发送命令,表示要成为Leader。

在T2时刻,S3判断主库为“客观下线”,它也想成为Leader,所以也先给自己投一张赞成票,再分别向S1和S2发送命令,表示要成为Leader。

在T3时刻,S1收到了S3的Leader投票请求。因为S1已经给自己投了一票Y,所以它不能再给其他哨兵投赞成票了,所以S1回复N表示不同意。同时,S2收到了T2时S3发送的Leader投票请求。因为S2之前没有投过票,它会给第一个向它发送投票请求的哨兵回复Y,给后续再发送投票请求的哨兵回复N,所以,在T3时,S2回复S3,同意S3成为Leader。

在T4时刻,S2才收到T1时S1发送的投票命令。因为S2已经在T3时同意了S3的投票请求,此时,S2给S1回复N,表示不同意S1成为Leader。

这里你可能会有疑问?为什么我们不能先接受到S1的投票请求,我们这里只是举个例子,真实场景也确实可能存在,比如 S2和S3之间的网络通信正常,但是S2和S1之间的通信不正常,这个时候就先接受到S3的投票请求。

最后,在T5时刻,S1得到的票数是来自它自己的一票Y和来自S2的一票N。而S3除了自己的赞成票Y以外,还收到了来自S2的一票Y。此时,S3不仅获得了半数以上的Leader赞成票,也达到预设的quorum值(quorum为2),所以它最终成为了Leader。接着,S3会开始执行选主操作,而且在选定新主库后,会给其他从库和客户端通知新主库的信息。

还有一种情况就是S3没有拿到2票Y,那么这轮投票就不会产生Leader。哨兵集群会等待一段时间(也就是哨兵故障转移超时时间的2倍),再重新选举。

为啥呢?

这是因为,哨兵集群能够进行成功投票,很大程度上依赖于选举命令的正常网络传播。如果网络压力较大或有短时堵塞,就可能导致没有一个哨兵能拿到半数以上的赞成票。所以,等到网络拥塞好转之后,再进行投票选举,成功的概率就会增加。

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

b836a35e1a6c0b31132ab10c6fd52d03.png

哈哈哈哈哈哈 没想到还没结束吧,我再抛个问题,如果哨兵选举的过程中,每个哨兵都选了自己,那是不是就无法选出leader,陷入死循环?

答案就是肯定不会出现陷入死循环,为什么呢?

一方面出现这种情况很难,就是因为不同哨兵之间的网络连接系统压力都不一样,判断主库客观下线的时间点相同的概率比较小。

其实哨兵对主从库在线状态监测,是属于一种时间事件,用一个定时器完成,一般来说每个哨兵的定时器的执行周期加一个小小的随机时间,目的就是为了错开时间,为了避免上述情况发生。

当然,你说我就巧了,正好同时发生了,那也不用慌,哨兵会停一段时间,然后再进行下一轮投票。

所以必不可能陷入死循环!!!

都到这了,点个赞再遛呗!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值