侧边栏壁纸
  • 累计撰写 247 篇文章
  • 累计创建 16 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

基于 PubSub 实现 Redis 哨兵集群以及哨兵与主从库之间的通信

kaixindeken
2021-08-12 / 0 评论 / 0 点赞 / 114 阅读 / 1,730 字

基于 PubSub 实现哨兵集群通信

哨兵容器之间可以相互感知并构建起哨兵集群,要归功于 Redis 内置的 PubSub 功能。

在配置哨兵实例时,只需要配置主库 IP 地址和端口号即可,这样一来,一旦该哨兵容器启动后,就会通过这个信息与主库建立连接并在该主库发布自己的 IP 地址和端口号,与此同时,该哨兵容器也会订阅该主库发布的信息,如果有其他哨兵发布了自己的 IP 地址和端口号可以立即获取到,这样就完成了不同哨兵容器之间的感知,从而构建起一个哨兵集群。

我们知道,为了避免不同类型消息收发的混乱,不同类型消息会被推送到不同的频道,订阅该频道的客户端只能接收到该频繁发布的消息,对于哨兵和主库的发布订阅机制而言,使用的是一个名为「sentinel:hello」的频道,不同哨兵容器就是通过它来相互发现,实现互相通信的。

哨兵除了彼此之间需要相互通信,以便进行选主和主从切换,还要能够与从库进行连接和通信,以便对从库进行监控、选定新的主库、以及通知其他从库新的主库信息。这一块在配置的时候并没有显式设置,底层又是如何自动实现的呢?

哨兵如何感知从库 IP 地址和端口号

在主库执行 info replication 指令就可以获取从库信息:

1.png

因此,哨兵建立与主库的连接后,只需要在主库上执行同样的命令就可以获取从库 IP 地址和端口号信息了,非常简单。接下来,哨兵就可以根据从库列表中的连接信息,和每个从库建立连接,并在这个连接上持续地对所有从库进行监控。

当然,哨兵构建集群以及和主从库建立连接并进行监控,只是工作的开始,而不是终点,后面还有很多其他更复杂的工作,比如选主、主从切换、通知从库。

如何确定执行主从切换的哨兵实例

我们已经在前面介绍过哨兵集群选主的大致流程,这里有一个问题,多个哨兵都可以判定主库的下线状态,但是最后执行主从切换的只能是某一个哨兵容器,否则就要乱套了,那么哨兵集群是如何确定这个最终执行主从切换的哨兵容器呢?

既然哨兵集群是一个分布式集群,那么和判定主库「客观下线」一样,这也可以通过少数服从多数的民主选主来实现:

  • 任何一个哨兵判断主库「主观下线」后,就可以给其他哨兵节点发送 is-master-down-by-addr 命令,然后其他实例会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成,N 相当于反对,如果收到的 Y 数大于 quorum 配置值,则可以判定主库「客观下线」了。
  • 接下来,就是选主阶段了。对于让哪个哨兵执行主从切换,每个哨兵在一开始都有平等的竞争机会。我们假设在一个包含三个节点(编号 A、B、C)的哨兵集群中,哨兵 A 最先判定主库「客观下线」,然后发出「由我进行主从切换」命令;
  • 紧接着,哨兵 B 也判断主库「主观下线」,然后给其他节点发送了同样的命令;
  • 在投票决定由谁进行主从切换时,每个哨兵在发出命令时,会先给自己投一票,并且已经投过票(含自己)的就不能再给其他哨兵投票了,因此这里决胜的关键在于哨兵 C;
  • 由于网络问题,先发出命令的哨兵 A 晚于哨兵 B 将消息发送到哨兵 C,因此哨兵 C 把自己的一票投给了 B,这个时候,哨兵 B 拿到的投票数大于等于 quotum 配置值,则系统判定由哨兵 B 执行主从切换。

我们把最终执行主从切换的哨兵称为 Leader,因此上述过程也称之为 Leader 选举。在分布式系统中,这是非常常见的操作。

如何通知其他从库建立新的主从关系

根据前面介绍的选主策略选取新的主库后,就可以通知其他从库与新的主库建立主从连接了。

这个通知也是基于 PubSub 完成的:和哨兵可以从 Redis 主库订阅消息一样,Redis 从库也可以从哨兵那里订阅消息,因为本质上来说,它们都是不同的 Redis 实例。

不同的事件对应着不同的频道,我们将常见的罗列如下:

1.png

很多都是我们在 Redis 哨兵容器日志中看到过的。比如新主库切换事件对应的频道是 +switch-master。

除了从库之外,Redis 客户端也可以监听这些频道,这样,在 Redis 主库完成切换,就可以及时与最新的主库建立连接,避免连接到老的主库出现无法写入的状况。

小结

综上,通过 PubSub 机制,我们就可以轻松建立 Redis 哨兵与主库、哨兵与哨兵、哨兵与从库、以及哨兵与客户端之间的关联,让主从集群和哨兵集群密切协作,进而保证 Redis 的高可用。

0

评论区