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

一、前言

Redis 的主从复制(Replication)是 Redis 高可用架构的基础之一。

通过复制机制,可以实现数据的冗余备份读写分离负载均衡 ,并为后续的哨兵(Sentinel)集群(Cluster)提供支撑。

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


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

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

  1. 建立连接阶段(主从握手)

  2. 数据同步阶段(全量复制或部分复制)

  3. 命令传播阶段(实时增量同步)

整体思想是:

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


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

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

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

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

这条命令表示:

  • "我没有历史同步信息(第一次连接)"

  • "请告诉我该从哪里开始复制"

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

  • 如果是第一次连接 → 返回 +FULLRESYNC <run_id> <offset>(全量复制)

  • 如果 run_id 匹配且 offset 合法 → 返回 +CONTINUE(部分复制)


关键点解释:

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

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

全量复制(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 反馈机制

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

java 复制代码
REPLCONF ACK <offset>

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

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


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

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

  • 检测连接是否健康;

  • 校准复制偏移;

  • 保证命令传播的连续性。


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

repl-backlog-size 默认 1MB,可根据网络稳定性与写入频率适当调整。

缓冲区越大,从节点掉线后越容易进行部分同步而非全量同步。


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

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

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

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

十、结语

Redis 的主从复制机制虽然本质上是异步的,但其通过 PSYNC 协议、replication backlog buffer、ACK 反馈机制等设计,实现了高效、可靠的复制能力。

理解其内部原理,不仅有助于我们调优高可用架构,也为深入掌握 Redis Sentinel 和 Cluster 打下了坚实基础。

相关推荐
luopandeng3 小时前
amd npt技术 对比 intel ept 技术
java·linux·网络
编啊编程啊程3 小时前
兼职管理平台
java·spring boot·rpc·dubbo·nio
梁辰兴3 小时前
计算机操作系统:进程同步
网络·缓存·操作系统·进程·进程同步·计算机操作系统
吃饭最爱3 小时前
java项目中前后端结合的要点
java
陈一Tender4 小时前
JavaWeb后端实战(IOC+DI)
java·spring boot·spring
Seven974 小时前
Spring AOP、MVC高频面试题解析
java·spring
极限实验室4 小时前
Elasticsearch 备份:snapshot 镜像使用篇
数据库·elasticsearch
kakacc:4 小时前
SpringBoot+Hutool+Vue实现导出
java·vue.js·spring boot
海底列车4 小时前
ubuntu-20.04.6升级OpenSSH_10.2p1
linux·服务器·ubuntu