4. Redis 高可用架构:主从复制、哨兵模式与 Cluster 分片
在生产环境中,Redis 单节点存在单点故障与容量瓶颈。本章深入剖析 Redis 三种高可用架构的核心原理、数据分布策略与选型依据,帮助你在企业业务系统中构建稳定、可扩展的缓存层。
4.1 主从复制:读写分离与数据冗余
主从复制是 Redis 高可用的基础。一个主节点(Master)负责写操作,多个从节点(Slave)同步数据并提供读服务,实现读写分离与数据冗余。
4.1.1 复制流程
- 连接建立:从节点向主节点发送
PSYNC命令,请求同步。 - 全量复制:主节点执行
BGSAVE生成 RDB 快照,发送给从节点;同时将新写入命令缓存到复制缓冲区。 - 增量复制:从节点加载 RDB 后,主节点将缓冲区中的增量命令发送给从节点,保持最终一致。
- 命令传播:后续主节点每次执行写命令,都会异步推送给所有从节点。
关键指标:主从复制延迟通常 < 1ms(同机房),跨机房可能达到 10-50ms。建议使用
INFO replication 监控 master_repl_offset 与 slave_repl_offset 的差值。
4.1.2 配置示例
# 从节点 redis.conf
replicaof 192.168.1.10 6379
replica-read-only yes
replica-serve-stale-data yes
repl-backlog-size 64mb # 复制积压缓冲区,避免全量复制
4.1.3 主从复制架构图
4.2 哨兵模式:自动故障检测与切换
哨兵(Sentinel)是一个分布式监控系统,负责监控主从集群的健康状态,并在主节点故障时自动执行故障转移,将某个从节点提升为新的主节点。
4.2.1 哨兵核心功能
| 功能 | 说明 | 关键参数 |
|---|---|---|
| 监控 | 定期向所有节点发送 PING,检测是否存活 | down-after-milliseconds |
| 自动故障转移 | 当主节点被标记为客观下线,哨兵集群选举 Leader 执行切换 | quorum(投票数) |
| 通知 | 通过 API 或脚本通知客户端新的主节点地址 | sentinel notification-script |
| 配置提供 | 客户端通过哨兵获取当前主节点信息 | sentinel monitor |
4.2.2 哨兵模式架构图
4.2.3 故障转移流程
- 主观下线:单个哨兵发现主节点 PING 超时,标记为
sdown。 - 客观下线:哨兵集群通过
sentinel is-master-down-by-addr通信,当投票数达到quorum,标记为odown。 - Leader 选举:哨兵集群使用 Raft 算法选举一个 Leader 负责故障转移。
- 从节点晋升:Leader 从从节点中选出一个优先级最高、数据最新的节点,执行
slaveof no one提升为 Master。 - 重新配置:其余从节点指向新 Master,哨兵更新配置并通知客户端。
避坑指南:哨兵模式无法解决写容量瓶颈,所有写请求仍集中在单主节点。当写 QPS 超过单机上限(通常 5-10 万/s)时,必须引入 Redis Cluster。
4.3 Redis Cluster:分片原理与数据分布
Redis Cluster 是官方提供的分布式解决方案,通过数据分片实现水平扩展,支持自动故障转移,无中心化架构。
4.3.1 分片核心机制
- 槽位分配:整个键空间被划分为 16384 个哈希槽(slot),每个节点负责一部分槽位。
- 键路由:对 key 使用 CRC16 算法计算哈希值,再对 16384 取模,得到槽位编号。
- MOVED 重定向:客户端访问的节点不负责该槽位时,返回
MOVED错误,告知正确节点地址。 - ASK 重定向:槽位迁移过程中,源节点返回
ASK错误,引导客户端访问目标节点。
4.3.2 数据分布示例
| 节点 | 负责槽位范围 | 槽位数量 | 示例 Key 路由 |
|---|---|---|---|
| Node A (192.168.1.1:6379) | 0 – 5460 | 5461 | user:1001 → slot 1024 |
| Node B (192.168.1.2:6379) | 5461 – 10922 | 5462 | order:2024 → slot 8000 |
| Node C (192.168.1.3:6379) | 10923 – 16383 | 5461 | session:abc → slot 15000 |
4.3.3 Redis Cluster 架构图
4.3.4 槽位计算与 hash tag
// 槽位计算伪代码
slot = CRC16(key) % 16384
// 使用 hash tag 强制将多个 key 分配到同一槽位
// 格式:{tag}key
// 示例:{user:1001}name 和 {user:1001}age 都在同一槽位
// 适用于事务、Lua 脚本等需要多 key 操作的场景
4.4 三种架构对比与选型
| 维度 | 主从复制 | 哨兵模式 | Redis Cluster |
|---|---|---|---|
| 高可用 | 手动切换 | 自动故障转移 | 自动故障转移 |
| 写容量 | 单节点瓶颈 | 单节点瓶颈 | 水平扩展 |
| 读容量 | 从节点扩展 | 从节点扩展 | 多节点扩展 |
| 数据分片 | 不支持 | 不支持 | 16384 槽位 |
| 客户端复杂度 | 低 | 中(需集成哨兵) | 高(需支持 Cluster 协议) |
| 适用场景 | 读多写少、数据量小 | 需要自动 HA、写 QPS < 5 万 | 写 QPS > 5 万、数据量 > 100GB |
选型建议:
- 缓存层写 QPS < 3 万,数据量 < 50GB → 哨兵模式(3 主 3 从)
- 写 QPS 5-20 万,数据量 100GB-1TB → Redis Cluster(6 主 6 从起步)
- 超大规模(写 QPS > 50 万,数据量 > 5TB)→ 考虑 Codis / Redis Cluster 分片 + 业务层 hash 预分区
- 缓存层写 QPS < 3 万,数据量 < 50GB → 哨兵模式(3 主 3 从)
- 写 QPS 5-20 万,数据量 100GB-1TB → Redis Cluster(6 主 6 从起步)
- 超大规模(写 QPS > 50 万,数据量 > 5TB)→ 考虑 Codis / Redis Cluster 分片 + 业务层 hash 预分区
4.5 热点削峰与架构结合
在热点削峰场景中,Redis 高可用架构的选择直接影响削峰效果:
- 哨兵模式 + 读写分离:热点 key 的读请求分散到多个从节点,减轻主节点压力。
- Cluster 分片 + 本地缓存:热点 key 通过 hash tag 集中到少数节点时,可在客户端增加本地缓存(如 Caffeine)兜底。
- 故障转移对削峰的影响:哨兵或 Cluster 切换期间(通常 10-30 秒),写请求可能失败,需在业务层设计重试与降级策略。
生产实践:某电商大促场景下,Redis Cluster 12 节点承载 30 万 QPS 写流量,通过预分片(提前将热点商品 key 分散到不同槽位)避免单节点过热,配合客户端本地缓存将读 QPS 降低 60%。