本文是大数据系列第 51 篇,介绍 Redis 高可用架构的核心机制:主从复制、哨兵模式与分布式锁设计。
高可用基础概念
高可用(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)
首次连接或数据差距过大时触发:
- 从节点发送
PSYNC ? -1请求全量同步 - 主节点执行
BGSAVE生成 RDB 快照 - 主节点将 RDB 文件传输给从节点
- 从节点加载 RDB,期间主节点缓冲的写命令也一并发送
- 进入增量同步状态
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