Redis进阶 - 高可用:哨兵机制(Sentinel)

本文讲解哨兵模式。

介绍

Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。

假设你用了 Redis(一个内存数据库)来做缓存或快速数据读写。那如果这个 Redis 的主 (master)节点突然挂了,怎么办呢?数据停了、服务挂了…这就很糟糕。
为了解决这个问题,Redis 提供了一个机制,叫做 Redis Sentinel(哨兵机制)。它可以:

  • 监控 Redis 的主从节点,看看谁坏了。
  • 当主节点坏了,自动切换一个从 (slave)节点变成新的主节点。
  • 通知客户端:原来的主节点挂了、新主节点是谁。
  • 帮客户端找到“当前哪台是主节点”。

下图是一个典型的哨兵集群监控的逻辑图:

哨兵集群的组建原理

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

在主从集群中,主库上有一个名为__sentinel__:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。在下图中,哨兵 1 把自己的 IP(172.16.19.3)和端口(26579)发布到__sentinel__:hello频道上,哨兵 2 和 3 订阅了该频道。那么此时,哨兵 2 和 3 就可以从这个频道直接获取哨兵 1 的 IP 地址和端口号。有了ip地址,那么哨兵们可以建立网络连接。

通过这个方式,哨兵 2 和 3 也可以建立网络连接,这样一来,哨兵集群就形成了。它们相互间可以通过网络连接进行通信,比如说对主库有没有下线这件事儿进行判断和协商。

哨兵监控Redis库

哨兵监控什么呢?怎么监控呢?

  • 主节点(master):主节点负责处理写操作,监控主节点是否挂了,时刻保持服务高可用。
  • 从节点(slave):复制主节点的数据,用于读取或备份,主节点挂了从节点可以选举为主节点。

监控是哨兵向主库发送 INFO 命令来完成的, 哨兵通过这个命令拿到 Redis 节点当前的运行状态。

哨兵与Redis建立连接:如下图所示,哨兵 2 给主库发送 INFO 命令,主库接受到这个命令后,就会把从库列表(Slave)返回给哨兵。接着,哨兵就可以根据从库列表中的连接信息,和每个从库建立连接,并在这个连接上持续地对从库进行监控。哨兵 1 和 3 可以通过相同的方法和从库建立连接。

主库下线的判定

哨兵如何判断主库已经下线了呢?

首先要理解两个概念:主观下线客观下线

  • 主观下线:任何一个哨兵都是可以监控探测,并作出Redis节点下线的判断;单个哨兵判断出下线。
  • 客观下线:有哨兵集群共同决定Redis节点是否下线, 当客观下线成立,主库会被换掉。

当某个哨兵(如下图中的哨兵2)判断主库“主观下线”后,就会给其他哨兵发送 is-master-down-by-addr 命令。接着,其他哨兵会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票。

如果赞成票数(这里是2)是大于等于哨兵配置文件中的 quorum 配置项(比如这里如果是quorum=2), 则可以判定主库客观下线了。

哨兵集群的选举

判断完主库下线后,由哪个哨兵节点来执行主从切换呢?这里就需要哨兵集群的选举机制了。

选举出来的 leader 会执行主从切换的任务。

  • 选举过程:
  1. 每个 Sentinel 都可以向其他 Sentinel 发送一个为自己投票的命令(SENTINEL is-master-down-by-addr)。
  2. 在配置的超时时间内,率先获得超过半数(quorum配置的数)选票的 Sentinel 成为领导者。
  3. 这是一个 Raft-like 的分布式共识算法,保证了在任何时候,最多只有一个领导者。
  • 任何一个想成为 Leader 的哨兵,要满足两个条件:

  • 第一,拿到半数以上的赞成票;

  • 第二,拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。

新主库的选出

主库既然判定客观下线了,那么如何从剩余的从库中选择一个新的主库呢?

  • 过滤掉不健康的(下线或断线),没有回复过哨兵ping响应的从节点
  • 选择salve-priority从节点优先级最高(redis.conf)的
  • 选择复制偏移量最大,只复制最完整的从节点

只能选出一个主库,如果有选出来两个主库,这就叫做脑裂

故障转移

故障转移 : 意思是把故障的节点切换到另一个健康的节点,上一步选举出来主库,这一步要做故障转移,自动恢复 Redis 的服务。

假设根据我们一开始的图:(我们假设:判断主库客观下线了,同时选出sentinel 3是哨兵 leader )

故障转移流程如下

  • 将slave-1脱离原从节点(PS: 5.0 中应该是replicaof no one),升级主节点,
  • 将从节点slave-2指向新的主节点
  • 通知客户端主节点已更换
  • 将原主节点(oldMaster)变成从节点,指向新的主节点

转移之后

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP