redis之哨兵集群(2)

前面提到过,如果一个哨兵在运行过程中发生故障,那么是不是还能进行主从库切换

实际上一旦多个实例组成了哨兵集群,即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作,包括判定主库是不是处于下线状态,选择新主库,以及通知从库和客户端。

配置哨兵所用到的信息:
sentinel monitor <master-name> <ip> <redis-port> <quorum>
需要主库名称 id 端口号 和哨兵判断主库客观下线所需投票数量

所以为了解决一个哨兵挂掉,不影响哨兵集群的正常使用,下面需要介绍哨兵集群的组成和运行机制

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

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

但是在在Redis实例上进行消息发布于订阅的不止哨兵,所以为了区分不同应用的消息,Redis 会以频道的形式,对这些消息进行分门别类的管理。所谓的频道,实际上就是消息的类别。当消息类别相同时,它们就属于同一个频道,反之,则不属于同一个频道,只有订阅了同一个频道的应用,才能通过发布的消息进行消息转换。

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

当所有哨兵集群之间相互通信时,哨兵集群就形成了,它们之间可以通过网络连接的方式进行通信,比如说对主库有没有下线这件事儿进行判断和协商。

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

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

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

哨兵会向主库发送info命令,主库就会把从库的列表返回给哨兵,哨兵就可以根据从库列表中的连接信息,和每个从库建立连接,并在这个连接上持续地对从库进行监控。

通过 pub/sub 机制,哨兵之间可以组成集群,同时,哨兵又通过 INFO 命令,获得了从库连接信息,也能和从库建立连接,并进行监控了。通过info信息还会返回关于主服务器本身的信息,包括服务器运行id以及服务器记录的服务器角色

主从库切换后,哨兵也需要将新主库信息告诉客户端这个任务。----------

每个哨兵实例也提供 pub/sub 机制,客户端可以从哨兵订阅消息。哨兵提供的消息订阅频道有很多,不同频道包含了主从库切换过程中的不同关键事件。

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

下面列举了一些常用的事件表

主观下线事件:+sdown 实例进入主观下线状态 -sdown 实例进入主观下线状态

+odown:实例进入客观下线状态 -odown:实例进入客观下线状态

接下来就要介绍,由哪个哨兵实例来进行主从服务器切换

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

当该实例获得仲裁所需的赞成票数后,就可以标记主库为客观下线状态,这个所需的赞成票数是通过哨兵配置文件中的 quorum 配置项设定的。

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

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

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

 

易弄混:哨兵会与主从服务器建立命令连接和订阅连接,而哨兵与哨兵之间只会建立订阅连接

每个与sentinel连接的服务器sentinel即通过命令连接向服务器的_sentinel_hello 频道发送信息,又通过订阅连接服务器的_sentinel_hello频道接受信息

 

posted @ 2020-10-16 09:58  xzwcomeon  阅读(104)  评论(0编辑  收藏  举报