从零起步学习Redis || 第十章:主从复制的实现流程与常见问题处理方案深层解析

44 阅读6分钟

一、前言

Redis 的主从复制(Replication)是 Redis 高可用架构的基础之一。
通过复制机制,可以实现数据的冗余备份读写分离负载均衡,并为后续的哨兵(Sentinel)集群(Cluster)提供支撑。

本文将从 Redis 的内部机制角度出发,深入分析主从复制是如何在底层实现的,包括核心流程、关键数据结构、协议交互和优化机制。


二、主从复制的整体流程概览

Redis 主从复制的整个过程可以分为 三个阶段

  1. 建立连接阶段(主从握手)
  2. 数据同步阶段(全量复制或部分复制)
  3. 命令传播阶段(实时增量同步)

整体思想是:

从节点通过 psync 命令与主节点进行握手,完成一次性数据同步(RDB + backlog),然后实时接收主节点写命令,从而保持与主节点数据一致。


三、阶段一:主从握手(连接建立)

当一个从节点启动并配置主节点地址后

,会主动向主节点发起复制请求:

PSYNC ? -1
?:主服务器的ID,因为第一次连接不知道主服务器的Id,所以用?表示
-1:复制的进度

这条命令表示:

  • “我没有历史同步信息(第一次连接)”
  • “请告诉我该从哪里开始复制”

主节点收到 PSYNC 请求后,会做以下判断:

  • 如果是第一次连接 → 返回 +FULLRESYNC <run_id> <offset>(全量复制)
  • 如果 run_id 匹配且 offset 合法 → 返回 +CONTINUE(部分复制)

关键点解释:

参数说明
run_id主节点实例的唯一标识符(每次重启会重新生成)
offset主从之间同步的“命令流偏移量”,用于标记同步进度
PSYNCRedis 复制协议的核心命令,用于协调全量或增量复制

四、阶段二:数据同步阶段

 全量复制(Full Resynchronization)

当主节点发现从节点没有旧数据或偏移信息时,就会触发全量复制。

内部执行过程如下:

  1. 主节点执行 BGSAVE

    • 创建后台子进程,生成当前内存数据的 RDB 快照;
    • 主线程继续响应客户端请求;
    • 所有新的写命令会暂存到 复制缓冲区(replication buffer) 中。
  2. 传输 RDB 快照

    • RDB 生成完毕后,主节点通过 socket 发送给从节点;
    • 从节点清空现有数据;
    • 从节点加载 RDB 文件,恢复数据。
  3. 发送 backlog 中的增量命令

    • 主节点会将 RDB 生成期间积累的命令(在复制缓冲区(replication buffer)中)同步发送给从节点;
    • 从节点执行这些命令,使数据状态追上主节点。

至此,第一次同步工作完成

优点: 保证数据完整
缺点: 对带宽和磁盘开销大,耗时较长


五、阶段三:命令传播阶段(实时同步)

一旦主从数据完全一致,主节点会持续地将新的写命令实时发送给从节点。(基于TCP长连接)

主节点的行为:

  • 每当执行一个写操作(如 SET key value):

    1. 写入主节点内存;
    2. 将命令追加到复制缓冲区;
    3. 异步发送给所有从节点。

从节点的行为:

  • 从节点以“伪客户端”的身份接收主节点发来的命令;
  • 解析后执行这些命令,更新自身数据;
  • 定期向主节点汇报自己的复制偏移量(offset)。

这个阶段是异步的:
主节点不会等待从节点确认即可向客户端返回结果。
因此可能存在数据丢失的风险(主节点宕机但命令尚未传播到从节点)。


六:问题:TCP连接断开一段时间后,又连接上了怎么办?

答:重新连接后,从节点psync主节点,开始增量复制这段时间的数据,因为主节点在传播命令时,还会把命令写入repl backlog buffer(环形缓存区,默认1m),从节点在psync会传递一个slave repl offset给主节点,主节点比较自身的master repl offset与s-r-o,从r-b-b中发送命令给复制缓冲区(replication buffer) ,但由于这是一个环形缓存区,如果断联时间过长,会导致一些命令的覆盖,此时就只能全量复制。

六、核心数据结构与机制

Redis 在主从复制中维护了一系列核心数据结构,用于记录同步状态和命令流。

名称作用说明
run_id主节点唯一标识用于判断主节点是否重启过
offset命令流偏移量每次写操作增加,用于同步进度
replication backlog buffer积压缓冲区固定大小的循环缓冲区(默认 1MB),存储最近的命令流
replication buffer复制缓冲区主节点为每个从节点单独维护的命令队列
PSYNC 命令同步协调命令实现全量与增量复制逻辑
client 结构体主从连接对象维护复制状态、缓冲区、偏移量等信息

七、复制中的辅助机制

1️⃣ ACK 反馈机制

从节点会定期向主节点发送:

REPLCONF ACK <offset>

表示“我已经同步到哪个偏移量”。

主节点通过该信息判断从节点延迟情况,并决定是否需要触发部分或全量复制。


2️⃣ 心跳机制(ping-pong心态检测机制)

主从之间会定期发送心跳包(PING/ACK),用于:

  • 检测连接是否健康;
  • 校准复制偏移;
  • 保证命令传播的连续性。

3️⃣ 复制积压缓冲区(Backlog)优化

repl-backlog-size 默认 1MB,可根据网络稳定性与写入频率适当调整。
缓冲区越大,从节点掉线后越容易进行部分同步而非全量同步。


八、复制过程总结图(文字版)

从节点启动
    ↓
发送 PSYNC ? -1
    ↓
主节点判断 → FULLRESYNC(全量) / CONTINUE(部分)
    ↓
[全量] 主节点执行 BGSAVE 生成 RDB → 传输给从节点
    ↓
[部分] 从 backlog 发送缺失命令流
    ↓
从节点加载 RDB 或执行增量命令 → 状态追平
    ↓
主节点持续异步发送写命令(命令传播阶段)
    ↓
从节点执行命令 + 汇报 offset


九、Redis 复制机制的特点与局限性

特性优点缺点
异步复制主节点性能高,延迟低有数据丢失风险
部分同步快速恢复中断连接依赖 backlog 缓冲区大小
全量同步确保一致性对大数据量成本高
多从复制支持一主多从主节点网络压力大

十、结语

Redis 的主从复制机制虽然本质上是异步的,但其通过 PSYNC 协议、replication backlog buffer、ACK 反馈机制等设计,实现了高效、可靠的复制能力。
理解其内部原理,不仅有助于我们调优高可用架构,也为深入掌握 Redis Sentinel 和 Cluster 打下了坚实基础。