哨兵挂了,主从库能切换吗

哨兵机制实现了监控、选主、通知功能。如果多个实例组成了哨兵集群,即使有哨兵实例出现了故障,其他哨兵还能继续协作完成主从库切换的工作,包括判断主库是不是处于下线状态,选择新主库,以及通知从库和客户端。

在配置哨兵信息时,只需要配置主库的IP和端口,并没有配置其他哨兵的连接信息。

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

那这些哨兵如何知道彼此的地址呢?

基于 pub/sub 机制的哨兵集群

哨兵只要和主库建立了连接,就可以在主库上发布消息了,比如说发布它自己的连接信息(IP和端口)。同时它也可以从主库上订阅消息,获得其他哨兵发布的连接信息。当多个哨兵实例都在主库上做了发布和订阅操作后,它们之间就能知道彼此的IP和端口。

除了哨兵实例,我们编写的应用程序也可以通过redis进行消息的发布和订阅。为了区分不同的应用消息,redis会以频道的形式,对这些消息进行分类。当消息类别相同时,它们就属于同一个频道。只有订阅了同一个频道的应用,才能通过发布消息进行信息交换。

在主从集群中,主库上有一个名为“sentinel:hello"的频道,不同哨兵就是通过它来相互发现,实现互相通信的。例如下图,
在这里插入图片描述
哨兵1把自己的IP和端口发布到“sentinel:hello” 频道上,哨兵 2和 3订阅了该频道。那么哨兵2和3就可以从这个频道直接获取哨兵1的连接信息了。然后哨兵 2和 3就可以和哨兵1建立网络连接。通过这个方式,哨兵2 和 3也可以建立网络连接,哨兵集群就这样形成了。它们之间就可以通过网络连接进行通信。

哨兵除了彼此之间建立起连接形成集群外,还需要和从库建立起连接。因为哨兵需要对主从库进行心跳判断,而且在主从库切换完成后,哨兵还需要通知从库,让它们和新主库进行同步。

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

这是由哨兵向主库发送 INFO 命令来完成的,如下图:
在这里插入图片描述
哨兵2向主库发送 INFO 命令,主库接受这个命令后,就把从库列表返回给哨兵。接着哨兵就可以根据从库列表中的连接信息,和每个从库建立起连接,并在这个连接上持续地对从库进行监控。哨兵1和3也可以通过相同的方法和从库建立起连接。

但是,哨兵不能只和主从库建立连接,因为主从库切换后,客户端也需要知道新竹库的连接信息,才能向新主库发送请求操作。所以,哨兵还需要完成把新主库的信息告诉客户端这个任务。

那么,**如何让客户端获取哨兵集群在监控、选主、切换这个过程中发生的各种事件呢?**还是基于 pub/sub 机制。

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

每个哨兵实例也提供了 pub/sub 机制,客户端可以从哨兵订阅消息。哨兵提供的消息订阅频道有很多,不同频道包含了主从切换过程中不同的关键事件。如下图:
在这里插入图片描述
客户端读取哨兵的配置文件后,可以获得哨兵的地址和端口,和哨兵建立连接。然后,在客户端执行订阅命令,获取不同的事件消息。

比如订阅所有实例进入客观下线状态事件:

SUBSCRIE +odown

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

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

有了这些事件通知,客户端就可以在主从切换后得到新主库的连接信息,还可以监控到主从库切换过程中发生的各个重要事件。这样客户端就可以知道主从切换到哪一步了。

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

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

哨兵集群要判定主库“客观下线”,需要有一定数量的实例都认为该主库已经“主观下线”。任何一定的哨兵实例只要自身判断主库“主观下线”后,就会给其他实例发送 is-master-down-by-addr 命令,然后其他实例就会根据自己当前和主库的连接情况,返回 Y(赞成) / N(反对) 响应。如下图:
在这里插入图片描述
一个哨兵获得了所需的赞成数后,就可以标记主库为“客观下线”。这个所需的赞成票数是通过哨兵配置文件中的 quorum 配置项设定的。例如,现在有 5 个哨兵,quorum 配置的是 3,那么一个哨兵需要 3 张赞成票,就可以把主库标记为“客观下线”了。这 3 张赞成票其中包括哨兵自己的一张。

此时,这个哨兵就可以给其他哨兵发送命令,表示希望自己来执行主从切换,称为“leader 选举”。成为 leader 的条件:拿到半数以上的赞成票;拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。如下图:在这里插入图片描述
在 T1 时刻,S1 判断主库为 “客观下线” ,它想成为 leader,就先给自己投一票,然后分别向 S2 和 S3 发送命令,表示要成为 leader。

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

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

在 T4 时刻,S2 才收到了 T1 时 S1 发送的投票命令。但 S2 之前已经投了 S3 赞成票,所以,S2 不能再投赞成票了,回复 S1 N 表示不同意。

在 T5 时刻,S3 获得了半数以上的 leader 赞成票,也达到预设的 quorum 的值,最终成为了 leader。接着 S3 开始了选主,在选定主库后,会给其他从库和客户端通知新主库的信息。

如果 S3 没有拿到 2票 Y,那么这轮投票就不会产生 leader,哨兵集群会等待一段时间(哨兵故障转移超时时间的 2 倍),再重新选举。这是因为哨兵集群很大程度上依赖于选举命令正常的网络传播。如果网络压力大或短时堵塞,就可能导致没有一个哨兵能拿到半数以上的赞成票。所以,等网络拥塞好转后,再进行投票选举,成功率会增加。

特别地,如果哨兵集群只有 2 个实例,此时,一个哨兵要想成为 leader,就必须获得 2 票而不是 1 票。所以如果有个哨兵挂掉了,那么此时的集群就无法进行主从切换。因为,通常至少会配置 3 个哨兵实例。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值