3. 主从复制原理:全量复制与增量复制的流程与数据流图

Redis 主从复制是构建高可用架构的基石。当从节点(Slave)首次连接主节点(Master),或发生网络中断后重新连接时,Redis 会根据断连时长与复制积压缓冲区(Replication Backlog)的状态,自动选择全量复制(Full Resynchronization)或增量复制(Partial Resynchronization)。理解这两种模式的触发条件与数据流向,是诊断同步延迟、规划故障切换策略的前提。

3.1 全量复制:场景与流程

全量复制是代价最高的同步方式,主节点需要生成 RDB 快照并完整传输给从节点。触发场景包括:

  • 从节点首次建立主从关系(SLAVEOF 或 REPLICAOF 命令)。
  • 从节点断连时间过长,导致主节点的复制积压缓冲区已无法覆盖缺失的写命令。
  • 从节点主动发起 PSYNC ? -1 请求(表示无历史复制偏移量)。
关键指标:全量复制期间,主节点会 fork 子进程生成 RDB,若实例内存较大(如 10GB+),fork 耗时与 RDB 传输带宽将成为主要瓶颈。建议在全量复制期间监控 rdb_save_in_progress 与 master_repl_offset。

全量复制详细步骤

  1. 从节点发起 PSYNC:从节点向主节点发送 PSYNC ? -1,表示需要全量同步。
  2. 主节点返回 FULLRESYNC:主节点回复 +FULLRESYNC <run_id> <offset>,告知从节点自己的运行 ID 与当前复制偏移量。
  3. 主节点生成 RDB:主节点 fork 子进程执行 BGSAVE,生成当前内存快照。在此期间,主节点继续处理客户端请求,并将新写入的命令缓存到复制积压缓冲区。
  4. 传输 RDB 文件:主节点将 RDB 文件通过网络套接字发送给从节点。从节点先写入磁盘,再加载到内存。
  5. 缓冲区命令同步:RDB 加载完成后,主节点将生成 RDB 期间累积的缓冲区命令发送给从节点,从节点执行这些命令以追上最新状态。
  6. 建立长连接:此后,主从进入增量复制阶段,主节点持续推送写命令到从节点。
全量复制数据流图 主节点 (Master) 从节点 (Slave) 客户端写入 RDB 快照 复制缓冲区 网络发送 接收 RDB 加载到内存 执行缓冲区 提供服务 ① PSYNC ? -1 ② +FULLRESYNC ③ 传输 RDB 文件 ④ 缓冲区增量命令 ⚠ 全量复制期间 主节点内存可能翻倍

3.2 增量复制:触发条件与核心机制

增量复制是 Redis 主从同步的常态模式。当从节点断连后重新连接,且断连时间较短,主节点的复制积压缓冲区仍保留着从节点缺失的写命令时,主节点仅发送缺失的部分,避免全量 RDB 传输。

最佳实践:合理设置 repl-backlog-size(默认 1MB)。对于写入量大的业务,建议设置为 64MB~256MB,以容纳更多增量命令,减少全量复制的触发概率。可通过 INFO replication 查看 repl_backlog_active 与 repl_backlog_histlen。

增量复制核心要素

组件 作用 配置参数
复制积压缓冲区 主节点维护的环形缓冲区,记录最近执行的写命令 repl-backlog-size
复制偏移量 (Replication Offset) 主从各自维护的字节偏移量,用于对齐同步位置 master_repl_offset / slave_repl_offset
运行 ID (Run ID) Redis 实例启动时生成的唯一标识,用于判断主节点是否变更 run_id
PSYNC 协议 从节点发送 PSYNC <run_id> <offset> 请求增量同步 内置协议

增量复制流程

  1. 从节点发送 PSYNC:从节点携带之前同步的主节点 run_id 与自己的复制偏移量,发送 PSYNC <run_id> <offset>。
  2. 主节点校验:主节点检查 run_id 是否匹配,以及从节点偏移量是否仍在复制积压缓冲区的有效范围内。
  3. 返回 CONTINUE:若校验通过,主节点回复 +CONTINUE,表示可以进行增量同步。
  4. 发送缺失命令:主节点从复制积压缓冲区中取出从节点偏移量之后的所有写命令,发送给从节点。
  5. 从节点执行:从节点接收并执行这些命令,更新自己的复制偏移量,与主节点保持一致。
增量复制数据流图 主节点 (Master) 从节点 (Slave) 持续写入 复制缓冲区 (环形队列) 偏移量校验 断连重连 接收增量 执行命令 ① PSYNC run_id offset ② +CONTINUE ③ 发送缺失的增量命令 ④ 确认偏移量一致 ✅ 增量复制效率高 不产生 RDB 传输

3.3 全量复制 vs 增量复制:对比总结

对比维度 全量复制 增量复制
触发条件 首次连接 / 断连超缓冲区 / 主节点重启 断连时间短,偏移量仍在缓冲区范围内
数据传输量 整个 RDB 文件 + 缓冲区增量 仅缺失的写命令
主节点负载 高(fork + RDB 生成 + 网络传输) 低(仅读取缓冲区并发送)
从节点阻塞时间 长(RDB 加载期间不可服务) 短(命令执行几乎无感)
网络带宽消耗 高(可能达到 GB 级别) 低(KB ~ MB 级别)
适用场景 新节点加入 / 灾难恢复 日常断连重连 / 网络抖动恢复
避坑指南:不要将 repl-backlog-size 设置过小。如果业务写入峰值达到 10MB/s,而 backlog 仅 1MB,那么从节点断连 0.1 秒就会触发全量复制。建议根据 master_repl_offset 的增长速率与期望的断连容忍时间,计算合适的 backlog 大小:backlog_size = 写入速率 × 容忍断连时间 × 1.5。