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。
全量复制详细步骤
- 从节点发起 PSYNC:从节点向主节点发送
PSYNC ? -1,表示需要全量同步。 - 主节点返回 FULLRESYNC:主节点回复
+FULLRESYNC <run_id> <offset>,告知从节点自己的运行 ID 与当前复制偏移量。 - 主节点生成 RDB:主节点 fork 子进程执行
BGSAVE,生成当前内存快照。在此期间,主节点继续处理客户端请求,并将新写入的命令缓存到复制积压缓冲区。 - 传输 RDB 文件:主节点将 RDB 文件通过网络套接字发送给从节点。从节点先写入磁盘,再加载到内存。
- 缓冲区命令同步:RDB 加载完成后,主节点将生成 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> 请求增量同步 |
内置协议 |
增量复制流程
- 从节点发送 PSYNC:从节点携带之前同步的主节点
run_id与自己的复制偏移量,发送PSYNC <run_id> <offset>。 - 主节点校验:主节点检查
run_id是否匹配,以及从节点偏移量是否仍在复制积压缓冲区的有效范围内。 - 返回 CONTINUE:若校验通过,主节点回复
+CONTINUE,表示可以进行增量同步。 - 发送缺失命令:主节点从复制积压缓冲区中取出从节点偏移量之后的所有写命令,发送给从节点。
- 从节点执行:从节点接收并执行这些命令,更新自己的复制偏移量,与主节点保持一致。
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。