问题: 高可用架构之主从复制:请说明 Redis 主从复制的全量同步与增量同步(PSYNC)流程;复制偏移量、复制积压缓冲区在断线重连后的部分重同步中起什么作用?

👇 点击展开/折叠 面试背诵模板(建议先背这个) Redis 主从复制分为全量同步和增量同步。全量同步用于初次复制或断线过久,主节点执行 BGSAVE 生成 RDB 快照并发送给从节点,同时将期间的写命令存入复制缓冲区一并发送。增量同步(PSYNC)用于断线重连后,从节点发送 PSYNC 命令携带复制偏移量,主节点检查该偏移量是否仍在复制积压缓冲区中,若在则只发送缺失的增量命令。复制偏移量记录主从各自已复制的数据字节数,用于判断数据一致性。复制积压缓冲区是主节点维护的固定大小循环队列(默认 1MB),保存最近传播的写命令,决定能否进行增量同步。
---

全量同步(Full Resynchronization)完整流程

全量同步发生在从节点首次连接主节点,或从节点的复制偏移量已不在主节点的复制积压缓冲区中时。

详细步骤:

  1. 从节点发起请求:从节点向主节点发送 PSYNC ? -1 命令请求同步。
  2. 主节点生成 RDB:主节点执行 BGSAVE 在后台生成 RDB 快照文件,同时用复制缓冲区记录此期间执行的所有写命令。
  3. 传输 RDB 文件:主节点将 RDB 文件发送给从节点。
  4. 从节点加载 RDB:从节点清空自身旧数据,载入接收到的 RDB 文件,将数据库状态更新至主节点执行 BGSAVE 时的状态。
  5. 发送缓冲命令:主节点将复制缓冲区中记录的写命令发送给从节点,从节点执行这些命令追平数据。
  6. 进入命令传播:同步完成后,主从进入命令传播阶段,主节点持续将写命令异步发送给从节点。

增量同步(Partial Resynchronization)完整流程

增量同步用于从节点与主节点网络短暂中断后重连的场景,前提是从节点的复制偏移量仍存在于主节点的复制积压缓冲区中。

详细步骤:

  1. 从节点发送 PSYNC:从节点重连后发送 PSYNC <replicationid> <offset> 命令,携带上次复制的复制 ID 和偏移量。
  2. 主节点检查条件:主节点比对复制 ID 和偏移量,判断从节点的偏移量是否仍在复制积压缓冲区范围内。
  3. 返回 +CONTINUE:若条件满足,主节点返回 +CONTINUE 表示可以进行部分重同步。
  4. 发送增量数据:主节点将复制积压缓冲区中从该偏移量之后的所有写命令发送给从节点。
  5. 从节点执行命令:从节点接收并执行这些命令,追上主节点数据。

若主节点返回 +FULLRESYNC,则表示条件不满足,将触发全量同步。

复制偏移量(Replication Offset)的作用

  • 主从各自维护:主节点和从节点分别维护一个复制偏移量,记录已复制的数据字节数。
  • 更新规则:主节点每次向从节点传播 N 字节数据时,偏移量加 N;从节点每次收到 N 字节数据时,偏移量加 N。
  • 判断一致性:通过对比主从节点的复制偏移量,可以快速判断主从数据是否一致。
  • 断线重传依据:从节点重连时将自身偏移量发送给主节点,主节点据此判断应执行全量还是增量同步。

复制积压缓冲区(Replication Backlog)的作用

  • 本质:主节点维护的一个固定大小的先进先出(FIFO)环形队列,默认大小为 1MB。
  • 存储内容:保存主节点最近传播的所有写命令,并为队列中的每个字节记录对应的复制偏移量。
  • 决定同步方式:当从节点重连并发送偏移量后,主节点检查该偏移量之后的数据是否仍在积压缓冲区中。若存在,执行增量同步;若已被覆盖(偏移量过旧),则触发全量同步。
  • 配置建议:积压缓冲区大小应根据网络状况和业务写入量合理设置(如 repl-backlog-size 64mb),过小会导致频繁全量同步。

服务器运行 ID(Run ID)的作用

  • 唯一标识:每个 Redis 节点启动时生成一个唯一的运行 ID(Run ID)。
  • 主节点变更检测:从节点会记录主节点的 Run ID,重连时发送给主节点。若 Run ID 不匹配(如主节点重启),说明从节点之前复制的主节点和当前连接的不是同一台服务器,将触发全量同步。

PSYNC 命令的三种响应

响应 含义 后续操作
+FULLRESYNC <runid> <offset> 执行全量同步 从节点记录 runid 和 offset,准备接收 RDB
+CONTINUE 执行增量同步 从节点等待接收积压缓冲区中的增量命令
-ERR 主节点版本过低 不支持 PSYNC,回退到 SYNC 命令