Redis是基于哨兵(Sentiel)实现高可用
一. 哨兵的介绍
sentinel,中文名是哨兵。sentinel本质上是运行在特殊模式下的Redis服务器
哨兵主要有以下几个功能:
- 故障转移:如果master节点挂了,会自动转移到slave节点上
- 集群监控:监控master和slave节点是否正常工作
- 消息通知:如果某个节点故障了,哨兵负责发送告警信息
- 配置中心:如果发生了故障转移,告知client新的master地址
哨兵用于实现redis集群的高可用,本身就是分布式的,是作为一个哨兵集群去运行的,哨兵之间互相协同工作:
- 故障转移时,判断一个master是否宕机,需要大部分的哨兵都同意,涉及到分布式选举的问题。
- 即使部分哨兵节点挂掉,哨兵集群还是能够正常工作的
二. 哨兵集群怎么组建的
在创建初始化sentinel的时候,sentinel会创建两个连接到master节点的连接
- 命令连接:用于向master发送命令并获取返回结果
- 订阅连接:专门用于订阅master的__sentinel__:hello频道
命令连接是sentinel给master发送命令使用;
__sentinel__:hello频道主要是用来给多个哨兵之间互相发现,比如哨兵1将自己的ip和端口信息pub到master的这个频道,那么订阅了这个频道的哨兵2肯定就能知道哨兵A的信息;此时哨兵1和2就能建立命令连接:
三. 哨兵怎么监控Redis集群
哨兵会跟master建立一个命令连接。哨兵2给master发送INFO命令,master收到这个命令会返回两个信息:
- master自身的信息,包括run_id域记录的服务器运行id,以及role域记录的服务器角色
- 还有是master下单的所有slave服务器信息,每个slave服务器都由一个“slave”字符串开发的行来记录,每行都记录了slave服务器的ip地址和端口信息。通过此信息,sentinel可以自己发现slave服务器。
同样的 当sentinel拿到slave服务器信息时,也会建立到slave服务器的命令连接和订阅连接
以下是INFO命令返回信息示例:
1 | # server |
四. master下线怎么判定
master下线分为主观下线和客观下线
- 主观下线:任何一个哨兵都是可以监控探测,并作出Redis节点下线的判断;
- 客观下线:有哨兵集群共同决定Redis节点是否下线;
当某个哨兵(如下图中的哨兵2)判断主库“主观下线”后,就会给其他哨兵发送 is-master-down-by-addr 命令。接着,其他哨兵会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票。
如果赞成票数(这里是2)是大于等于哨兵配置文件中的 quorum 配置项(比如这里如果是quorum=2), 则可以判定主库客观下线了。

五. 选举领头Sentinel
为了保证高可用,哨兵一般都是作为哨兵集群存在的。作为集群,必然会涉及到选举问题,就是主节点选举问题。因为控制redis的故障转移和通知只需要一个主的哨兵节点。
所以在master(主库)客观下线后,先要选出一个Leader sentinel以进行后面的故障转移和通知操作。
哨兵的选举机制就是经典的Raft选举算法:
选举的票数大于一半的哨兵数时,将成为主哨兵节点,否则继续选举。
任何一个想成为Leader的哨兵,都首先要满足这两个条件:
- 拿到半数以上的选票
- 拿到的票数要大于等于哨兵配置文件中的quorum值。
举个例子
现在有3个哨兵组成一个哨兵集群,此时配置的quorum=2,那么任何一个想成为Leader的哨兵只要能拿到2张选票就可以。
因为拿到2张票,2>半数哨兵 且 2>=quorum
六. 故障转移
选出Leader哨兵后,它将会对已下线的主库进行故障转移操作,主要是三个步骤:
- 在已下线的主节点的所有从节点中,挑选一个从节点,并将其转为主节点
- 让已下线的主节点下的所有从节点改为复制新的主节点
- 将已下线的主节点设置为新的主节点的从节点,当旧的主节点重新上线时,他就成为新的主节点的从节点。
选出新的主节点
新的主节点如何挑选,Leader哨兵将旧的主节点的所有从节点保存到一个列表,然后按照以下规则,一项一项过滤
- 删除列表中所有断线的从节点
- 删除列表中最近5s没有回复过Leader哨兵INFO命令的从节点
- 删除所有与已下线主节点连接断开
down-after-milliseconds*10毫秒的从服务器 - 再根据
salve-priority配置的优先级,对剩余的从节点进行排序,选择优先级最高的从节点 - 如果有优先级相同的,选择复制偏移量最大的
- 如果还有多个按照run-id,选择run-id最小的

