Redis 主从复制、哨兵和集群模式有什么区别?高可用方案怎么选?
Redis 的主从复制、哨兵模式和集群模式是三种不同层次的高可用方案,它们解决的核心问题不同,选择时需要根据业务的数据规模、可用性要求和读写瓶颈来决定。
主从复制:解决读瓶颈和数据备份
主从复制是最基础的方案。一个 Redis 节点作为 Master 负责写操作,一个或多个 Slave 节点从 Master 同步数据,只提供读服务。
同步过程分两个阶段:首次连接时 Master 执行 BGSAVE 生成 RDB 快照发送给 Slave(全量同步);之后的写命令通过 repl-backlog 缓冲区持续发送给 Slave(增量同步)。如果 Slave 断开时间过长,缓冲区被覆盖,就会再次触发全量同步。
bashslaveof 192.168.1.100 6379
主从复制的核心价值是读写分离——把读流量分散到多个 Slave 上,同时 Slave 作为数据副本提供冗余。但它的致命问题是 Master 挂了之后需要人工介入,把某个 Slave 手动提升为 Master,还要修改应用配置指向新地址,恢复时间完全取决于运维响应速度。
适用场景:数据量不大、读多写少、能容忍短暂不可用的内部系统。比如配置中心、排行榜这类读远多于写的业务。
哨兵模式:在主从基础上实现自动故障转移
哨兵模式本质是主从复制 + 自动化运维。部署一组 Sentinel 进程(至少3个,奇数个),它们持续监控 Master 和 Slave 的状态,Master 故障时自动完成故障转移。
故障转移的核心机制:主观下线与客观下线
单个 Sentinel 检测到 Master 无响应(超过 down-after-milliseconds),标记为主观下线(SDOWN)。但这可能只是网络抖动,所以需要多个 Sentinel 互相确认——当超过 quorum 个数的 Sentinel 都认为 Master 下线时,才标记为客观下线(ODOWN),此时才会触发真正的故障转移。
故障转移流程
- Sentinel 集群通过 Raft 协议选出一个 Leader Sentinel 执行转移
- Leader 从 Slave 中选出新 Master(优先判断复制偏移量最大、连接最稳定的节点)
- 对新 Master 执行
SLAVEOF NO ONE,将其提升为主节点 - 通知其他 Slave 复制新 Master
- 更新 Sentinel 的监控配置
bashport 26379 sentinel monitor mymaster 192.168.1.100 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel failover-timeout mymaster 180000
配置中 2 表示至少需要 2 个 Sentinel 同意才能判定客观下线。生产环境建议至少部署 3 个 Sentinel,跨机房分布,避免 Sentinel 自身成为单点。
客户端需要使用 Sentinel 模式连接——先从 Sentinel 获取当前 Master 地址,再连接 Master。当故障转移完成后,Sentinel 会通知客户端切换到新 Master。
局限性
哨兵解决了自动故障转移,但写操作仍然只能走 Master 单点,存储容量也受限于单机内存。当数据量超过单机内存,或者写 QPS 成为瓶颈时,哨兵模式就不够用了。
适用场景:数据量在单机内存范围内,但需要高可用、要求故障自动恢复的业务。大部分中小规模的生产环境用哨兵模式就足够了。
集群模式:解决写瓶颈和存储瓶颈
Redis Cluster 是真正的分布式方案,通过数据分片把数据分散到多个 Master 节点上,每个 Master 持有部分数据,同时可以有自己的 Slave 做副本。
哈希槽分片机制
Cluster 把整个键空间划分为 16384 个哈希槽,每个 Master 负责一部分槽。客户端写入一个 key 时,用 CRC16(key) % 16384 计算出槽编号,然后路由到负责该槽的节点。
当集群需要扩容时,只需把一部分哈希槽从旧节点迁移到新节点,不需要停服。收缩时反向操作。
请求重定向:MOVED 和 ASK
客户端向错误节点发送请求时,该节点会返回重定向指令:
- MOVED:表示该槽已经永久迁移到新节点,客户端应更新本地缓存
- ASK:表示该槽正在迁移中(临时状态),客户端本次请求转发到目标节点,但不更新缓存
bashcluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000
创建集群:
bashredis-cli --cluster create \ 192.168.1.1:7000 192.168.1.2:7001 192.168.1.3:7002 \ 192.168.1.4:7003 192.168.1.5:7004 192.168.1.6:7005 \ --cluster-replicas 1
节点通信与故障检测
Cluster 采用 Gossip 协议进行节点间通信,每个节点定期向其他节点发送 PING 消息交换集群状态。当某个 Master 被超过半数 Master 标记为故障(PFAIL → FAIL),其 Slave 会自动提升为新 Master。
限制
- 不支持跨槽的多键操作(
MGET、MSET等操作的 key 必须在同一槽,可用 hash tag{tag}解决) - 不支持跨槽的
WATCH事务 KEYS、SCAN等命令只能看到当前节点的数据- 最少需要 6 个节点(3 主 3 从)才能保证高可用
适用场景:数据量超过单机内存、写 QPS 单机无法承载、需要在线扩缩容的大规模业务。
三种方案的核心区别
| 特性 | 主从复制 | 哨兵模式 | 集群模式 |
|---|---|---|---|
| 故障转移 | 手动 | 自动(Sentinel 选举) | 自动(Gossip + 投票) |
| 写扩展 | 不支持 | 不支持 | 支持(数据分片) |
| 存储扩展 | 受限于单机 | 受限于单机 | 支持(水平扩容) |
| 最小部署 | 2 节点 | 2 Redis + 3 Sentinel | 6 节点(3主3从) |
| 运维复杂度 | 低 | 中 | 高 |
| 客户端要求 | 普通 | 支持 Sentinel 协议 | 支持 Cluster 协议 |
面试中如何回答
面试官问这个问题,核心考察的是你对 Redis 高可用演进路径的理解,而不只是背诵概念。建议从问题驱动的角度组织回答:
第一步,先说清楚每种方案解决什么问题——主从解决读瓶颈,哨兵解决自动故障转移,集群解决写瓶颈和存储瓶颈。这三个是递进关系,不是并列选择。
第二步,结合实际场景给出选型依据:数据量小 + 可容忍短时不可用 → 主从;数据量小 + 要求高可用 → 哨兵;数据量大或写 QPS 高 → 集群。
第三步,补充生产经验。比如哨兵部署要跨机架、集群扩容时注意槽迁移对大 key 的影响、客户端重试策略要处理 MOVED/ASK 重定向等。这些细节能体现你的实战深度。