Redis Sentinel(哨兵)原理

一、基础概念

主从复制存在一个问题,没法完成自动故障转移。所以我们需要一个方案来完成自动故障转移,它就是Redis Sentinel(哨兵)

Redis Sentinel ,它由两部分组成,哨兵节点 和 数据节点

  • 哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控

  • 数据节点: 主节点和从节点都是数据节点;


在复制的基础上,哨兵实现了 自动化的故障恢复 功能,下面是官方对于哨兵功能的描述:

  • 监控(Monitoring): 哨兵会不断地检查主节点和从节点是否运作正常

  • 自动故障转移(Automatic failover): 当 主节点 不能正常工作时,哨兵会开始自动故障转移操作

它会将失效主节点的其中一个 从节点升级为新的主节点,并让其他从节点改为复制新的主节点

  • 配置提供者(Configuration provider): 客户端在初始化时,通过连接哨兵来获得当前 Redis 服务的主节点地址

  • 通知(Notification): 哨兵可以将故障转移的结果发送给客户端


二、Redis Sentinel(哨兵)实现原理

哨兵模式是通过哨兵节点完成对数据节点的 监控、下线、故障转移


定时监控

Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控:

1、每隔 10 秒,每个 Sentinel 节点会向主节点和从节点发送 info命令 获取最新的拓扑结构

2、每隔 2 秒,每个 Sentinel 节点会向Redis数据节点的 sentinel:hello 频道上发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息

3、 每隔 1 秒,每个 Sentinel 节点会向主节点、从节点、其它 Sentinel 节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可用


主观下线和客观下线


主观下线就是哨兵节点认为某个节点有问题,客观下线就是超过一定数量的哨兵节点认为主节点有问题


1、主观下线

每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过 down-after-milliseconds 没有进行有效回复,

Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线


2、客观下线

当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过 sentinel is- master-down-by-addr命令 向其他Sentinel节点询问对主节点的判断,

当超过 quorum(投票)个数,Sentinel节点认为主节点确实有问题,这时该 Sentinel节点会做出客观下线的决定


3、领导者Sentinel节点选举

Sentinel节点之间会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。Redis使用了Raft算法实现领导者选举


4、故障转移

领导者选举出的Sentinel节点负责故障转移,过程如下:


1、在从节点列表中选出一个节点作为新的主节点,这一步是相对复杂


2、Sentinel 领导者节点会对第一步选出来的从节点执行 slaveof no one命令让其成为主节点


3、Sentinel 领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点


4、Sentinel 节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点


三、领导者Sentinel节点选举

Redis使用了Raft算法实 现领导者选举,大致流程如下:


1. 每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令, 要求将自己设置为领导者


2. 收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的 sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝


3. 如果该Sentinel节点发现自己的票数已经大于等于 max(quorum, num(sentinels)/2+1), 那么它将成为领导者


4. 如果此过程没有选举出领导者,将进入下一次选举


四、领导者Sentinel节点如何挑选新的主节点


选出新的主节点,大概分为这么几步:


1. 过滤:“不健康”(主观下线、断线)、5秒内没有回复过 Sentinel节点 ping 响应、与主节点失联超过 down- after-milliseconds*10秒


2. 选择 slave-priority(从节点优先级) 最高的从节点列表,如果存在则返回,不存在则继续


3. 选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续


4. 选择 runid最小的从节点

posted @ 2025-04-28 21:09  jock_javaEE  阅读(58)  评论(0)    收藏  举报