主从数据同步
约 1125 字大约 4 分钟
2025-09-02
全量同步
全量同步发生在 Slave 节点首次连接 Master 或数据差异过大时,涉及完整数据集的传输。
全量同步流程
- 同步请求:Slave 向 Master 发送同步请求,声明自身 replid 和 offset。
- 首次同步判断:Master 校验 Slave 的 replid:
- 若与 Master 的 replid 不同,判定为第一次同步,进入全量流程。
- 版本信息返回:Master 返回自身 replid 和 offset,Slave 保存该信息。
- RDB 文件生成:
- Master 执行
BGSAVE命令,生成 RDB 快照文件。 - 生成期间,Master 将新写入命令记录到
repl_baklog(内存缓冲区)。
- Master 执行
- RDB 文件传输:Master 发送 RDB 文件至 Slave。
- 数据加载与命令重放:
- Slave 清空本地数据,加载 RDB 文件。
- Master 发送
repl_baklog中的缓冲命令,Slave 执行以同步最新数据。
判断是否为第一次同步
Master 通过比对 replid 判断是否首次同步;offset 用于增量同步时的数据定位:
- Replication ID (replid):
- 唯一标识数据集,Master 生成唯一 replid,Slave 继承 Master 的 replid。
- 若 Slave 的 replid 与 Master 不同,则判定为第一次同步(需全量同步)。
- Offset(偏移量):
- 记录
repl_baklog中的命令位置,随数据写入递增。 - 若 Slave 的 offset 小于 Master,说明数据落后,但仅当 replid 一致时才触发增量同步。
- 记录
增量同步
增量同步适用于 Slave 短暂断连后恢复连接,仅传输差异数据,提升效率。
增量同步流程
- 同步请求:Slave 向 Master 发送同步请求,携带自身 replid 和 offset。
- 非首次同步判断:Master 校验 replid 一致且 offset 有效,返回
CONTINUE响应。 - 命令传输:Master 根据 Slave 的 offset,从
repl_baklog缓冲区提取未同步命令并发送。 - 命令执行:Slave 接收并执行命令,完成数据同步。
注
复制积压缓冲区(repl_backlog)是一个固定大小的环形缓冲区。如果 Slave 断开连接的时间过长,导致其需要同步的 offset 对应的数据已经被 Master 的新数据覆盖,Master 将无法提供增量同步所需的数据。在这种情况下,Master 会强制 Slave 进行全量同步。
实践优化
全量同步资源消耗高(磁盘 I/O、网络 I/O),优化目标包括减少全量同步频率、提升效率及降低 Master 负载。
针对全量同步的优化思路
- 开启无磁盘复制(Diskless Replication):
- 配置
repl-diskless-sync yes。 - 启用后,Master 在进行全量同步时将不再生成 RDB 文件到磁盘,而是直接将 RDB 数据通过网络流式传输给 Slave。
- 这可以显著减少磁盘 I/O,提高全量同步的效率,尤其是在 SSD 性能不佳或磁盘 I/O 成为瓶颈的环境中。但会增加 Master 的网络 I/O 压力。
- 配置
- 控制 Redis 单节点内存占用:
- 较小的内存占用意味着 RDB 文件更小,从而减少全量同步时的磁盘 I/O(如果未开启无磁盘复制)和网络 I/O。
- 合理规划数据存储,避免单个 Redis 实例存储过大数据量。
- 减少全量同步的概率:
- 适当提高
repl_backlog内存缓冲区的大小:- 通过配置
repl-backlog-size参数来调整。 - 更大的缓冲区可以保留更长时间的命令历史,从而允许 Slave 在断开连接较长时间后仍能进行增量同步,减少全量同步的发生。
- 缓冲区大小应根据 Master 的写入速度和 Slave 的平均断线时间来估算。
- 通过配置
- 尽快实现故障恢复:当 Slave 宕机时,应尽快恢复,以避免其断连时间过长,导致
repl_backlog中的数据被覆盖。
- 适当提高
优化 Master 同步压力
如果存在大量 Slave 节点直接连接到 Master 进行数据同步,Master 的 CPU、内存和网络带宽都可能成为瓶颈。
- 限制一个 Master 上的 Slave 节点数量:
- 根据 Master 的硬件资源和网络带宽,合理限制直接连接的 Slave 数量。
- 采用主 - 从 - 从链式复制结构:
- 在大型部署中,可以采用链式复制(
Master -> Slave1 -> Slave2 -> ...)或树状复制结构。 - 这种方式可以分散 Master 的复制压力,提高整体系统的可伸缩性。但需要注意,链条越长,数据同步的延迟可能越高。
- 在大型部署中,可以采用链式复制(