高 进阶
Redis哨兵机制#
一句话答案#
Sentinel 监控主从节点健康状态,主库故障时自动选举新主库并通知客户端,实现高可用。
核心要点
Sentinel 的三大功能:
| 功能 | 说明 |
|---|---|
| 监控(Monitoring) | 持续检测主从节点是否正常运行 |
| 自动故障转移(Failover) | 主节点宕机时,自动将某个从节点提升为新主节点 |
| 通知(Notification) | 故障转移完成后通知客户端新主节点地址 |
Sentinel 部署架构:
┌──────────┐
│ Sentinel │ (至少 3 个,奇数个)
│ 集群 │
└────┬─────┘
│ 监控
┌──────────┼──────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ Master │→│ Slave1 │ │ Slave2 │
└────────┘ └────────┘ └────────┘
异步复制plaintext主节点下线判断过程:
1. 主观下线(SDOWN):
单个 Sentinel 向主节点发送 PING,超过 down-after-milliseconds(默认 30s)未收到有效回复
→ 该 Sentinel 认为主节点"主观下线"(仅是自己的判断)
2. 客观下线(ODOWN):
该 Sentinel 询问其他 Sentinel:"你也认为主节点下线了吗?"
如果超过 quorum(法定票数,通常为 Sentinel 总数的一半+1)个 Sentinel 都同意
→ 主节点被标记为"客观下线"(集群共识)
→ 触发故障转移plaintext故障转移流程:
1. Sentinel 选举 Leader:
在 Sentinel 集群中选出一个 Leader(Raft 算法),由 Leader 执行故障转移
2. 选择新主节点(Leader Sentinel 执行):
① 过滤掉不健康的 Slave(断线时间过长的)
② 按优先级排序(slave-priority,值越小优先级越高)
③ 优先级相同 → 选复制偏移量最大的(数据最新)
④ 偏移量也相同 → 选 runId 最小的
3. 执行切换:
① 向选中的 Slave 发送 SLAVEOF NO ONE(提升为 Master)
② 向其他 Slave 发送 SLAVEOF <新Master>(重新指向新主)
③ 通知客户端新主节点地址(通过 Pub/Sub 频道 +switch-master)plaintextSentinel 的局限性:
- 写操作仍集中在单个 Master 节点,无法水平扩展写能力
- 存储容量受限于单节点内存
- 故障转移期间有短暂不可用窗口(秒级)
- 适用于读多写少、数据量可单机承载的场景
面试回答(2分钟版)
Sentinel 哨兵是 Redis 实现高可用的核心组件,承担监控、自动故障转移和通知三大职责。部署上至少三个奇数个 Sentinel 节点。故障判定分两步:单个 Sentinel 对主节点 PING 超时未响应标记为主观下线 SDOWN,然后询问其他 Sentinel,超过 quorum 票数同意则标记为客观下线 ODOWN,触发故障转移。转移流程是先在 Sentinel 之间用 Raft 算法选出一个 Leader,再由 Leader 从存活的从节点中选新主:优先过滤不健康的,然后按优先级排序,优先级相同选复制偏移量最大即数据最新的,再相同选 runId 最小的。选好后向新主发 SLAVEOF NO ONE 提升为主,向其他从库发 SLAVEOF 指向新主,最后通过 Pub/Sub 通知客户端更新连接地址。哨兵的局限是写能力受限于单主节点,不能水平扩展,数据量超出单机内存就需要升级到 Cluster。
追问与易错
追问方向:
- “哨兵选主规则?”→ 先过滤不健康的从节点(断线过久的),再按 slave-priority 优先级排序(值越小越优先),优先级相同选复制偏移量最大的(数据最新),偏移量也相同选 runId 最小的
- “客户端怎么感知主切换?”→ 客户端订阅 Sentinel 的 +switch-master 频道(Pub/Sub),故障转移完成后 Sentinel 通过该频道推送新主节点地址;Jedis/Lettuce 等客户端 SDK 内置了自动订阅和重连机制
- “一个哨兵够吗?”→ 不够,单个 Sentinel 无法形成多数派投票,既无法可靠判定客观下线,也存在 Sentinel 自身单点故障风险;至少部署 3 个奇数个 Sentinel 节点
易错点:
- ❌ 哨兵能防数据丢失——切换期间可能丢部分数据
- ❌ 哨兵和 Cluster 二选一——职责不同