再谈谈redis如何保证高可用
2023-04-10

Redis是基于哨兵(Sentiel)实现高可用

一. 哨兵的介绍

sentinel,中文名是哨兵。sentinel本质上是运行在特殊模式下的Redis服务器

哨兵主要有以下几个功能:

  • 故障转移:如果master节点挂了,会自动转移到slave节点上
  • 集群监控:监控master和slave节点是否正常工作
  • 消息通知:如果某个节点故障了,哨兵负责发送告警信息
  • 配置中心:如果发生了故障转移,告知client新的master地址

哨兵用于实现redis集群的高可用,本身就是分布式的,是作为一个哨兵集群去运行的,哨兵之间互相协同工作:

  • 故障转移时,判断一个master是否宕机,需要大部分的哨兵都同意,涉及到分布式选举的问题。
  • 即使部分哨兵节点挂掉,哨兵集群还是能够正常工作的

二. 哨兵集群怎么组建的

在创建初始化sentinel的时候,sentinel会创建两个连接到master节点的连接

  1. 命令连接:用于向master发送命令并获取返回结果
  2. 订阅连接:专门用于订阅master的__sentinel__:hello频道

命令连接是sentinel给master发送命令使用;
__sentinel__:hello频道主要是用来给多个哨兵之间互相发现,比如哨兵1将自己的ip和端口信息pub到master的这个频道,那么订阅了这个频道的哨兵2肯定就能知道哨兵A的信息;此时哨兵1和2就能建立命令连接

三. 哨兵怎么监控Redis集群

哨兵会跟master建立一个命令连接。哨兵2给master发送INFO命令,master收到这个命令会返回两个信息:

  1. master自身的信息,包括run_id域记录的服务器运行id,以及role域记录的服务器角色
  2. 还有是master下单的所有slave服务器信息,每个slave服务器都由一个“slave”字符串开发的行来记录,每行都记录了slave服务器的ip地址和端口信息。通过此信息,sentinel可以自己发现slave服务器。

同样的 当sentinel拿到slave服务器信息时,也会建立到slave服务器的命令连接订阅连接

以下是INFO命令返回信息示例:

1
2
3
4
5
6
7
8
# server
run_id: xxxxxxxxxxxxxxxxxxxxxx
# Replication
role: master

slave0:ip=192.168.1.2,port=1111,state=online,offset=43,lag=0
slave1:ip=192.168.1.3,port=1112,state=online,offset=43,lag=0
slave2:ip=192.168.1.4,port=1113,state=online,offset=43,lag=0

四. master下线怎么判定

master下线分为主观下线客观下线

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

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

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

1

五. 选举领头Sentinel

为了保证高可用,哨兵一般都是作为哨兵集群存在的。作为集群,必然会涉及到选举问题,就是主节点选举问题。因为控制redis的故障转移和通知只需要一个主的哨兵节点。

所以在master(主库)客观下线后,先要选出一个Leader sentinel以进行后面的故障转移和通知操作。

哨兵的选举机制就是经典的Raft选举算法:

选举的票数大于一半的哨兵数时,将成为主哨兵节点,否则继续选举。

任何一个想成为Leader的哨兵,都首先要满足这两个条件:

  1. 拿到半数以上的选票
  2. 拿到的票数要大于等于哨兵配置文件中的quorum值。

举个例子

现在有3个哨兵组成一个哨兵集群,此时配置的quorum=2,那么任何一个想成为Leader的哨兵只要能拿到2张选票就可以。
因为拿到2张票,2>半数哨兵2>=quorum

六. 故障转移

选出Leader哨兵后,它将会对已下线的主库进行故障转移操作,主要是三个步骤:

  1. 在已下线的主节点的所有从节点中,挑选一个从节点,并将其转为主节点
  2. 让已下线的主节点下的所有从节点改为复制新的主节点
  3. 将已下线的主节点设置为新的主节点的从节点,当旧的主节点重新上线时,他就成为新的主节点的从节点。

选出新的主节点

新的主节点如何挑选,Leader哨兵将旧的主节点的所有从节点保存到一个列表,然后按照以下规则,一项一项过滤

  1. 删除列表中所有断线的从节点
  2. 删除列表中最近5s没有回复过Leader哨兵INFO命令的从节点
  3. 删除所有与已下线主节点连接断开down-after-milliseconds*10毫秒的从服务器
  4. 再根据salve-priority配置的优先级,对剩余的从节点进行排序,选择优先级最高的从节点
  5. 如果有优先级相同的,选择复制偏移量最大的
  6. 如果还有多个按照run-id,选择run-id最小的