本文是大数据系列第 51 篇,介绍 Redis 高可用架构的核心机制:主从复制、哨兵模式与分布式锁设计。

完整图文版(含截图):CSDN 原文 | 掘金

高可用基础概念

高可用(High Availability)指系统在尽量减少计划外停机时间的前提下保持持续运行的能力,通常用”几个九”衡量:

SLA年停机时间上限
99.9%(3个9)约 8.76 小时
99.99%(4个9)约 52.6 分钟
99.999%(5个9)约 5.26 分钟

从 CAP 理论来看,Redis 高可用方案优先保证 A(可用性)P(分区容错性),在极端网络分区下可能出现短暂数据不一致。

实现高可用的四大支柱:冗余故障检测自动恢复负载均衡

Redis 主从复制

主从复制是 Redis 高可用的基础,从节点通过同步主节点数据提供读扩展和数据冗余。

配置方式

在从节点的 redis.conf 中添加:

replicaof 192.168.1.100 6379

或在运行时动态执行:

REPLICAOF 192.168.1.100 6379

三种同步模式

1. 全量同步(Full Sync)

首次连接或数据差距过大时触发:

  1. 从节点发送 PSYNC ? -1 请求全量同步
  2. 主节点执行 BGSAVE 生成 RDB 快照
  3. 主节点将 RDB 文件传输给从节点
  4. 从节点加载 RDB,期间主节点缓冲的写命令也一并发送
  5. 进入增量同步状态

2. 增量同步(Incremental Sync)

正常运行时,主节点将每条写命令实时发送给所有从节点,保持数据同步。

3. 心跳检测

从节点每隔 1 秒发送 REPLCONF ACK <offset> 命令,主节点据此判断从节点存活状态和同步偏移量。

常见拓扑结构

  • 一主多从:最常见,主节点负责写,从节点负责读
  • 链式复制:从节点再挂从节点,分散主节点的复制压力

Redis 哨兵模式(Sentinel)

哨兵模式在主从复制基础上增加了自动故障转移能力。哨兵是独立进程,持续监控 Redis 实例的健康状态。

哨兵的核心职责

职责说明
监控(Monitoring)通过 PING 命令持续检测主从节点存活状态
通知(Notification)发现异常时通过 API 通知管理员或其他程序
自动故障转移(Failover)主节点下线时,自动选举新主节点并重新配置从节点
配置提供(Config Provider)客户端通过哨兵获取当前主节点地址

故障检测与转移流程

单个哨兵检测主节点无响应

主观下线(SDOWN):该哨兵认为主节点疑似故障

哨兵间投票确认(需达到 quorum)

客观下线(ODOWN):多数哨兵确认主节点故障

Raft 算法选举领导哨兵

领导哨兵执行故障转移:
  1. 从从节点中选出最优候选(优先级、复制偏移量)
  2. 将候选提升为新主节点
  3. 通知其他从节点改为复制新主
  4. 更新配置文件

Docker 部署示例

以下是一个完整的 docker-compose.yml,部署 1 主 2 从 + 3 哨兵:

version: '3'
services:
  redis-master:
    image: redis:7
    ports:
      - "6379:6379"

  redis-slave-1:
    image: redis:7
    ports:
      - "6380:6379"
    command: redis-server --replicaof redis-master 6379
    depends_on:
      - redis-master

  redis-slave-2:
    image: redis:7
    ports:
      - "6381:6379"
    command: redis-server --replicaof redis-master 6379
    depends_on:
      - redis-master

  sentinel-1:
    image: redis:7
    ports:
      - "26379:26379"
    command: redis-sentinel /etc/sentinel.conf
    depends_on:
      - redis-master
      - redis-slave-1
      - redis-slave-2

  sentinel-2:
    image: redis:7
    ports:
      - "26380:26379"
    command: redis-sentinel /etc/sentinel.conf
    depends_on:
      - redis-master

  sentinel-3:
    image: redis:7
    ports:
      - "26381:26379"
    command: redis-sentinel /etc/sentinel.conf
    depends_on:
      - redis-master

哨兵配置文件 sentinel.conf 核心参数:

# 监控名为 mymaster 的主节点,quorum=2 表示需要 2 个哨兵确认才客观下线
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

分布式锁基础

Redis 单机分布式锁的核心命令:

SET lock_key unique_value NX PX 30000
  • NX:仅在键不存在时设置(原子性抢锁)
  • PX 30000:设置 30 秒过期(防止死锁)

释放时需验证 value 是否属于当前持有者,通常使用 Lua 脚本保证原子性:

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

在哨兵模式下,主节点异常切换期间存在锁丢失风险(主节点写成功但从节点尚未同步)。生产环境建议评估是否需要 Redlock 算法或使用 ZooKeeper 等强一致性方案。

小结

  • 主从复制提供数据冗余和读扩展,是高可用基础
  • 哨兵模式在主从基础上增加自动故障转移,提升系统可用性
  • 分布式锁依赖 Redis 原子操作,但在高可用切换场景下需注意边界情况
  • 生产部署推荐至少 3 个哨兵节点,quorum 设为 (哨兵数/2) + 1