Redis-哨兵(sentinel)

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」关键词,及时告警。

Categories: 系统运维