redis主从复制

Redis 主从复制全流程深度解析

Redis 主从复制(Master-Slave Replication)全流程解析

Redis 主从复制是实现数据备份、读写分离、高可用的核心机制,简单说就是「主节点(Master)写数据,从节点(Slave)同步主节点数据并提供读服务」。下面从复制触发方式、完整同步流程、增量同步流程、核心细节四个维度,把整个过程讲透。

一、先明确核心角色与目标

  • 主节点(Master):可读写,负责接收所有写操作,是数据的「源头」;
  • 从节点(Slave):只读(默认),唯一任务是同步 Master 数据,分担读压力;
  • 核心目标
    • 数据冗余:Master 故障时,Slave 可升级为 Master 保障可用性;
    • 读写分离:Master 写、Slave 读,提升整体并发能力;
    • 负载均衡:分散读请求到多个 Slave。

二、复制的触发方式

从节点主动发起复制,有 2 种配置方式:

1. 配置文件方式(永久生效)

在 Slave 节点的 redis.conf 中添加:
# 指定主节点IP和端口
replicaof <master-ip> <master-port>
# 如果主节点设置了密码,需要配置认证
masterauth <master-password>

2. 运行时命令方式(临时生效,重启失效)

登录 Slave 节点执行:
# 关联主节点
127.0.0.1:6380> replicaof 127.0.0.1 6379
# 主节点有密码时,先认证
127.0.0.1:6380> auth <master-password>

三、完整同步(全量复制):Slave 首次连接 Master

这是最核心的流程,发生在 Slave 第一次连接 Master、或 Slave 断线后重连但无法进行增量同步时。整个过程分 6 步:

步骤 1:建立套接字连接(Socket)

  1. Slave 启动后,向 Master 发起 TCP 连接请求;
  2. Master 接收连接,创建「复制专用」套接字,双方建立长连接;
  3. 若连接失败(如网络不通、Master 密码错误),Slave 会每隔 1 秒重试(可通过 replica-ping-replica-period 配置)。

步骤 2:全量同步前的「握手协商」

  1. Slave 向 Master 发送 PING 命令,检测 Master 可用性;
  2. Master 回复 PONG,确认自身正常;
  3. 若 Master 设置了 requirepass,Slave 发送 AUTH 命令+密码,认证通过后才能继续;
  4. Slave 发送 REPLCONF listening-port <自身端口>,告诉 Master 自己的监听端口;
  5. Slave 发送 REPLCONF capa eof capa psync2,声明支持的复制能力(如 psync2 协议、EOF 检测)。

步骤 3:Slave 发起全量同步请求(PSYNC)

Slave 发送 PSYNC ? -1 命令:
  • ?:表示 Slave 不知道 Master 的「运行 ID」(首次连接);
  • -1:表示 Slave 没有偏移量(offset),需要全量同步。

步骤 4:Master 生成 RDB 快照(核心)

  1. Master 收到 PSYNC 后,执行 BGSAVE 命令,fork 子进程生成 RDB 快照文件;
  2. 生成 RDB 期间,Master 会把新收到的写命令(如 SET、HSET)写入「复制缓冲区」(repl backlog),避免数据丢失。

步骤 5:Master 发送 RDB 文件给 Slave

  1. Master 完成 RDB 生成后,通过套接字将 RDB 文件发送给 Slave;
  2. Slave 接收 RDB 文件,先清空自身原有数据(避免旧数据干扰),然后加载 RDB 到内存,恢复 Master 的数据快照。

步骤 6:Master 发送复制缓冲区的增量命令

  1. RDB 发送完成后,Master 把「生成 RDB 期间」写入复制缓冲区的所有写命令,一次性发送给 Slave;
  2. Slave 执行这些增量命令,使自身数据与 Master 完全一致;
  3. 至此,全量同步完成,进入「增量同步阶段」。

四、增量同步:正常运行时的实时同步

全量同步完成后,Master 与 Slave 进入稳定的增量同步阶段,核心是「Master 有写操作就实时推给 Slave」:
  1. Master 每执行一个写命令,都会把命令写入「复制缓冲区」(环形缓冲区,默认 1MB,可通过 repl-backlog-size 调整);
  2. Master 通过已建立的长连接,将写命令实时发送给所有 Slave;
  3. Slave 接收命令后,立即执行,保证与 Master 数据一致;
  4. 每个 Slave 会记录自己同步到的「偏移量(offset)」,Master 也会记录每个 Slave 的 offset,用于异常重连时判断是否需要全量同步。

五、断线重连后的同步逻辑(部分同步)

如果 Slave 因网络问题断线,重连后不会直接触发全量同步,而是先尝试「部分同步」:
  1. Slave 重连 Master 后,发送 PSYNC <master-runid> <slave-offset>
    1. master-runid:上次连接的 Master 运行 ID(唯一标识 Master);
    2. slave-offset:Slave 最后同步到的偏移量;
  2. Master 检查:
    1. master-runid 匹配(还是同一个 Master),且 Slave 的 offset 落在「复制缓冲区」的有效范围内 → 只发送 offset 之后的增量命令(部分同步);
    2. master-runid 不匹配(Master 更换),或 offset 超出缓冲区范围 → 触发全量同步。

六、核心细节与关键配置

1. 复制缓冲区(Repl Backlog)

  • 作用:缓存 Master 最新的写命令,供 Slave 断线重连时增量同步;
  • 配置:repl-backlog-size 1mb(默认),repl-backlog-ttl 3600(缓冲区无 Slave 连接时的存活时间);
  • 建议:读写频繁的场景,调大 repl-backlog-size(如 10MB),减少全量同步概率。

2. 复制偏移量(Offset)

  • Master 和 Slave 各自维护 offset:Master 记录发送的字节数,Slave 记录接收的字节数;
  • 可通过 info replication 查看:
    # Master 侧
    master_repl_offset: 12345
    # Slave 侧
    slave_repl_offset: 12345  # 与 Master 一致则同步正常

3. 运行 ID(Run ID)

  • Master 启动时生成的唯一 ID(如 878f966e7a97d889),Slave 会记录该 ID;
  • 若 Master 重启,Run ID 会变化,Slave 重连时会触发全量同步(Redis 4.0+ 支持 replica-no-one-detected 优化)。

4. 从节点只读

  • 默认 Slave 只读(slave-read-only yes),防止误写;
  • 如需临时写(如调试),可执行 config set slave-read-only no,但生产环境禁止。

5. 复制超时

  • 配置:repl-timeout 60(默认 60 秒),超过该时间无通信则断开连接;
  • 需保证 repl-timeout > repl-ping-replica-period(Slave 向 Master 发送 PING 的间隔,默认 10 秒)。

七、常见问题与避坑

  1. 全量同步耗时过长
    1. 原因:Master 数据量大,RDB 生成/传输慢;
    2. 解决:调大 Master 的 dbfilename 所在磁盘 IO 优先级,使用高速网络,或分批次同步(如先同步冷数据)。
  2. Slave 数据延迟
    1. 原因:网络延迟、Master 写压力大、Slave 执行命令慢;
    2. 解决:增加 Slave 节点分担读压力,优化 Master 写性能,缩短复制缓冲区超时时间。
  3. Master 故障后 Slave 数据不一致
    1. 原因:断线时 Master 有未同步的命令;
    2. 解决:结合哨兵(Sentinel)或 Redis Cluster,自动切换 Master 并保证数据一致性。

总结

  1. 全量同步:Slave 首次连接/重连无法增量同步时触发,流程为「建连接→协商→Master 生成 RDB→发送 RDB→发送增量命令→Slave 加载」;
  2. 增量同步:正常运行时,Master 实时推送写命令给 Slave,通过 offset 保证数据一致;
  3. 断线重连:优先尝试部分同步(基于复制缓冲区),失败则触发全量同步,核心依赖 Run ID 和 offset。
Redis 主从复制是哨兵(Sentinel)和集群(Cluster)的基础,掌握这个流程后,理解高可用架构会更轻松。如果需要,我可以补充「主从复制+哨兵」的完整部署示例。
posted @ 2026-03-14 17:44  ConfidentLiu  阅读(47)  评论(0)    收藏  举报