2. Redis主从复制与Sentinel的关系
Sentinel 本身并不复制数据,它只是“看护者”。真正承载数据冗余与读扩展能力的,是主从复制链路。理解 Sentinel 的高可用行为,必须先理解它监控的对象——一条由主节点和若干从节点组成的复制拓扑,以及这条链路上数据如何流动、延迟如何产生、故障切换后链路如何被重建。
一、主从复制的数据流与拓扑
Redis 主从复制采用异步复制模型。从节点通过 REPLICAOF(旧版本为 SLAVEOF)命令指向主节点后,会经历三个阶段:建立连接与握手、全量同步(RDB 快照传输)、增量同步(命令传播)。全量同步时,主节点执行 BGSAVE 生成 RDB 文件,同时用复制缓冲区记录这期间的新写命令;RDB 传输完成后,再把缓冲区中的命令补发给从节点。此后主节点每执行一条写命令,都会异步推送给所有从节点。
复制拓扑常见有三种形态:一主一从、一主多从(星型)、以及级联复制(从节点再挂从节点)。星型拓扑下主节点需要向每个从节点推送命令,从节点数量越多,主节点的网络与 CPU 开销越大;级联复制可以分摊主节点压力,但会叠加延迟。生产环境通常采用“一主两从 + 三 Sentinel”的经典组合,兼顾冗余与仲裁。
二、复制延迟:异步模型的固有代价
由于复制是异步的,主节点写入成功后立即向客户端返回,从节点的数据可能滞后于主节点。这个滞后量可以用两个指标衡量:复制偏移量(offset)差值和复制延迟秒数。通过 INFO replication 可以查看主从的 master_repl_offset 与 slave_repl_offset,两者之差就是尚未同步的字节数;master_last_io_seconds_ago 则反映从节点最近一次与主节点通信距今的秒数。
延迟的常见来源包括:主节点写入量突增导致复制缓冲区积压、网络带宽不足或抖动、从节点执行慢命令(如大 key 删除、KEYS)阻塞复制线程、以及从节点磁盘 I/O 瓶颈影响 RDB 落盘。延迟过大时,Sentinel 的故障切换可能造成数据丢失——因为被提升的从节点可能还没收到主节点最后的写命令。
三、故障切换对复制链路的影响
当 Sentinel 判定主节点客观下线(ODOWN)并完成领导者选举后,会从从节点中挑选一个“最合适”的节点提升为新主。选择依据依次是:优先级 replica-priority、复制偏移量最大、runid 最小。提升完成后,Sentinel 会向其余从节点发送 REPLICAOF 命令,让它们指向新主节点,从而重建复制链路。
这个过程对复制链路的影响体现在三方面:第一,原主节点恢复后会被 Sentinel 降级为从节点,重新加入链路;第二,切换期间存在一个“无主窗口”,此间写操作会失败,客户端需要重试或依赖 Sentinel 感知的新地址;第三,如果原主节点在切换前有未同步的写命令,这些数据将永久丢失。因此运维上必须关注 min-replicas-to-write 和 min-replicas-max-lag 参数,让主节点在从节点数量不足或延迟过大时拒绝写入,以降低切换丢数据的风险。
四、运维关注点与检查清单
日常运维中,应把复制链路健康度作为核心巡检项。以下是一份可直接参考的检查清单:
| 检查项 | 命令/指标 | 健康判断 | 异常处置 |
|---|---|---|---|
| 主从连接状态 | INFO replication 中 master_link_status |
up | down 时检查网络、密码、bind 配置 |
| 复制延迟 | master_last_io_seconds_ago |
小于 1 秒 | 持续大于 10 秒需排查慢命令与带宽 |
| 偏移量差距 | 主从 offset 差值 |
差值稳定且小 | 差值持续扩大说明复制积压 |
| 从节点只读 | replica-read-only |
yes | 防止误写从节点导致数据不一致 |
| 切换保护 | min-replicas-to-write |
建议设为 1 或 2 | 避免无健康从节点时仍接受写入 |
down-after-milliseconds 为 30000(30 秒),并配合 failover-timeout 180000(3 分钟),给足网络抖动与慢查询的容错窗口,避免误判切换。
WAIT 命令做同步复制确认,但这会牺牲部分写入性能。
总结来看,主从复制提供数据冗余与读扩展,Sentinel 提供故障发现与自动切换,二者是“数据面”与“控制面”的分工关系。运维的核心不是让 Sentinel 更快切换,而是让复制链路足够健康、延迟足够小,从而让切换的代价可控、数据损失可预期。