跳到正文

Redis Sentinel 哨兵模式 ​

一句话:Sentinel 是一组独立进程,用「主观下线 + 客观下线」把「主节点挂了」变成共识,再选一个 Leader 把副本提升为主;代价是切换窗口,以及必须有多数派同时存活。

适用版本:Redis 7.x / 8.x。Sentinel 自 2.8 引入,7.x 的参数名与行为基本稳定。

为什么需要 ​

主从复制只解决了「有副本」,没解决「主节点挂了谁来切」。人工切换要发现故障、确认数据、改配置、通知客户端,慢且容易出错。Sentinel 把这几步自动化:持续 PING、多节点确认、自动选主、通知客户端新地址。它只做高可用,不做数据分片;容量不够仍然要靠 Cluster。

核心机制 ​

主观下线与客观下线 ​

下线判定分两步:单个 Sentinel 的怀疑只是 SDOWN,凑够 quorum 个共识才升级成 ODOWN 并触发切换。

图中的 PING 对象不限于主节点:每个 Sentinel 每秒还会 PING 副本和其他 Sentinel,用于互相发现与健康检查。quorum 只决定「多少个 Sentinel 认同,才算客观下线」,不等于选主所需的多数派。

两个多数派,别混 ​

概念作用需要多少
quorum判定 ODOWNsentinel monitor 里配置的值
Leader 选举多数派授权某个 Sentinel 执行 Failover所有已知 Sentinel 的多数,即 N/2+1

例子:5 个 Sentinel,quorum=2。2 个 Sentinel 就能把主节点判成 ODOWN;但执行切换的 Leader 必须拿到 3 票。只满足 quorum 不满足多数派时,会一直停在 ODOWN,切不动。反过来,quorum 设得比多数派还大也没有意义。

Failover 流程 ​

  1. 某个 Sentinel 发现 ODOWN,发起 Leader 选举;每个 Sentinel 每轮只投一票,先到先得,超时时间带随机因子,避免同时竞选。
  2. Leader 从副本中选新主:排除主观/客观下线、最近未响应 PING、与旧主断开过久的副本;再按 replica-priority(默认 100,越小越优先)、复制 offset(越大越新)、runid 字典序依次比较。
  3. 对新主执行 REPLICAOF NO ONE,让其余副本 REPLICAOF 新主,更新 Sentinel 配置,旧主恢复后降级为副本。
  4. 客户端通过 SENTINEL get-master-addr-by-name 或支持 Sentinel 的客户端库拿到新地址。

切换总耗时通常在十几秒到几十秒,主要花在 down-after-milliseconds、确认和选举上。

Sentinel 会持久化状态 ​

Sentinel 不持久化数据集(没有 RDB/AOF),但会持续重写自己的配置文件 sentinel.conf,把运行状态落盘:

sentinel myid ...
sentinel monitor mymaster 10.0.0.1 6379 2
sentinel config-epoch mymaster 3
sentinel leader-epoch mymaster 3
sentinel current-epoch 3
sentinel known-replica mymaster 10.0.0.2 6379
sentinel known-sentinel mymaster 10.0.0.3 26379 <runid>

所以「Sentinel 不持久化」是错误说法:它持久化的是配置和共识状态,不是业务数据。重启后会从文件恢复已知副本、Sentinel 列表和 epoch;如果所有 Sentinel 的配置文件都丢了,才会丢失「谁是主、切换过几次」的历史。配置文件必须可写,否则状态无法落盘。

Sentinel 之间通过主节点的 __sentinel__:hello 频道(Pub/Sub)自动发现,不需要手工列出所有 Sentinel 地址。

最小上手 ​

conf
# sentinel.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
bash
redis-server /path/sentinel.conf --sentinel
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL replicas mymaster

生产动作 ​

  • 至少 3 个,最好奇数:3 个能容忍 1 个挂掉后仍形成多数派;2 个任意一个挂掉就无法选举。5 个用于更重要的集群。
  • 分散部署:Sentinel 不要和主节点同机房/同宿主机,否则一次故障全灭。
  • quorum 与多数派一起算:3 个 Sentinel 常用 quorum=2;5 个常用 quorum=3。quorum 太小会误判,太大则真故障时难以达成 ODOWN。
  • down-after-milliseconds 默认 30000:网络抖动多的环境适当调大,切换速度要求高的场景调小,但要先压测误判率。
  • parallel-syncs 默认 1:切换后同时向新主同步的副本数;调大能加快收敛,但会集中消耗新主带宽。
  • 配置认证:主从有密码时,Sentinel 也要配 sentinel auth-pass mymaster <password>,否则监控和切换都会失败。
  • 验证切换:定期用 SENTINEL failover mymaster 演练,检查客户端是否真的切到新地址。

边界 ​

  • 只做高可用,不做分片:所有节点仍存全量数据,容量和写吞吐受单机限制。
  • 不解决异步复制的丢数据:Sentinel 只负责选新主,新主可能比旧主少最近几秒的写入。
  • 少数派不能切换:网络分区时,处于少数派的一侧无法选出 Leader,会保持只读/不可写,这是有意的保护,不是 bug。
  • Sentinel 状态持久化不等于数据持久化:配置文件丢了会丢共识历史,业务数据仍要靠 RDB/AOF。
  • 客户端要支持 Sentinel:不会自动改 DNS 或 VIP;应用必须通过 Sentinel 查询主节点地址,或使用支持 Sentinel 的连接池。
  • 脑裂风险仍在:旧主在分区恢复前可能仍接受写入,切换后这部分写入会丢;需要结合 min-replicas-to-write 等参数降低风险。

讲清楚 ​

Sentinel 解决的是「主节点挂了以后自动切」。它由一组独立进程组成,每个进程每秒 PING 主从节点,超时就标记主观下线;当足够多的 Sentinel 都认同,才变成客观下线。注意 quorum 只负责判定下线,真正执行切换的 Leader 还要拿到所有 Sentinel 的多数票,这两个数不是一回事。

选出 Leader 后,它按优先级和复制 offset 选一个最新的副本提升为主,再让其他副本跟过去。Sentinel 会把发现到的副本、其他 Sentinel 和 epoch 写回配置文件,所以它持久化的是状态而不是数据;但异步复制导致的丢数据窗口,Sentinel 管不了。

把一门技术讲透到既懂也会用