Redis 哨兵模式(Redis Sentinel),是官方为解决 主从架构下主节点故障自动恢复问题而设计的高可用方案 —— 简单来说,哨兵模式就是给 Redis 主从集群配了一个 “智能监控管家”,它能自动监控主从节点的健康状态,主节点宕机时自动把最优的从节点晋升为主节点,还能通知客户端更新连接地址,全程无需人工干预。
哨兵模式的核心组件和架构
redis-master 主节点 处理写请求,是数据写入源
redis-slave 从节点1 处理读请求,同步主节点数据,主节点故障后可被晋升
redis-sentinel 哨兵节点 独立进程,至少部署3个(奇数),避免哨兵单点故障
哨兵节点之间也会互相通信,同步节点状态,避免 “单个哨兵误判”;哨兵节点不存储业务数据,仅负责监控和故障转移,资源消耗极低。
哨兵模式的核心工作流程
1、监控
每个哨兵节点会定期(默认 1 秒)向主节点、所有从节点、其他哨兵节点发送PING命令,检测节点是否存活;若节点在down-after-milliseconds(默认 30 秒)内未回复PONG,哨兵将其标记为 “主观下线(SDOWN)”(单个哨兵的判断);哨兵节点之间同步这个 “主观下线” 状态,若超过 quorum(配置的法定票数,如 3 个哨兵需 2 票) 的哨兵都判定该主节点下线,就标记为 “客观下线(ODOWN)”(集群共识,避免误判)。
2、故障转移
主节点被标记为 “客观下线” 后,哨兵集群会选举出一个 “领头哨兵”,由它执行故障转移:
筛选可用从节点:排除宕机、同步延迟过高、网络不可达的从节点;
选举最优从节点:按 “优先级(replica-priority)> 复制偏移量(数据同步完整性)> 运行 ID(小的优先)” 排序,选出最优从节点;
晋升主节点:领头哨兵向最优从节点发送SLAVEOF NO ONE命令,使其晋升为新主节点;
重定向其他从节点:向剩余从节点发送SLAVEOF 新主节点IP 端口命令,让它们同步新主节点的数据;
标记旧主节点:将宕机的旧主节点标记为 “已下线”,若其恢复上线,哨兵会让它成为新主节点的从节点。
3、通知客户端
哨兵会通过 “发布订阅” 机制(频道+switch-master),将新主节点的地址通知给所有连接的客户端,客户端收到后自动更新连接地址,无需重启。
4、持续监控
新主从集群建立后,哨兵继续监控所有节点,重复上述流程,保障高可用。
哨兵模式的核心配置(快速上手)
监听地址
bind 0.0.0.0
监听端口(第1个哨兵监听26379,第二个哨兵监听26380,第三个哨兵监听26381)
port 26379
配置监控的主节点(格式:sentinel monitor 主节点名称 IP 端口 法定票数)
sentinel monitor redis-master 172.22.0.4 6379 2
主节点主观下线超时时间(毫秒)
sentinel down-after-milliseconds redis-master 30000
故障转移超时时间(毫秒)
sentinel failover-timeout redis-master 180000
每次故障转移最多同步的从节点数(避免同时同步压垮新主节点)
sentinel parallel-syncs redis-master 1
若主节点有密码,需配置
sentinel auth-pass redis-master 123456
下面用docker来实现哨兵的搭建
1、redis-data的docker-compose:
services:
master:
image: 'redis'
container_name: redis-master
restart: always
command: redis-server --appendonly yes
ports:
- "6379:6379"
init: true
slave1:
image: 'redis'
container_name: redis-slave1
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- "6380:6379"
init: true
slave2:
image: 'redis'
container_name: redis-slave2
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- "6381:6379"
init: true
2、redis-sentinel的docker-compose:
services:
sentinel1:
image: 'redis'
container_name: redis-sentinel-1
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel1:/etc/redis:rw
ports:
- 26379:26379
sentinel2:
image: 'redis'
container_name: redis-sentinel-2
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel2:/etc/redis:rw
ports:
- 26380:26379
sentinel3:
image: 'redis'
container_name: redis-sentinel-3
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel3:/etc/redis:rw
ports:
- 26381:26379
networks:
default:
name: redis-data_default
external: true
./sentinel2/sentinel.conf
./sentinel1/sentinel.conf
./sentinel3/sentinel.conf
redis-sentinel 在运⾏中会对配置进⾏rewrite,修改⽂件内容,如果⽤⼀份⽂件,就可能出现修改混乱的情况
bind 0.0.0.0
port 26379
sentinel monitor redis-master 172.22.0.3 6379 2
sentinel down-after-milliseconds redis-master 1000
# 允许解析主机名(必须开启)
sentinel resolve-hostnames yes
# Generated by CONFIG REWRITE
dir "/data"
latency-tracking-info-percentiles 50 99 99.9
user default on nopass sanitize-payload ~* &* +@all
sentinel myid 3793d928f554a76865fc028766a4a74974ef9ae4
sentinel config-epoch redis-master 3
sentinel leader-epoch redis-master 3
sentinel current-epoch 3
sentinel known-replica redis-master 172.22.0.2 6379
sentinel known-replica redis-master 172.22.0.4 6379
sentinel known-sentinel redis-master 172.22.0.7 26379 05b0884fba827610d7b743669d16b0338a541467
sentinel known-sentinel redis-master 172.22.0.5 26379 d8353f71b0a292cf9ab56d6a2ecde9a7ef5ded4f
客户端规范:禁止客户端直接配置主节点 IP,必须通过哨兵地址获取主节点,适配+switch-master事件的自动重连。客户端使用支持哨兵自动发现的 Redis 客户端(如 Java 的 Jedis、Spring Data Redis),配置哨兵地址而非固定主节点地址。
监控规范:监控哨兵的INFO sentinel状态、主从节点的replication状态,监控日志中的「ODOWN」「FAILOVER」关键词,及时告警。