Redis主从同步的同步步骤和原理
本文最后更新于 2025-11-07,文章内容可能已经过时。
一、主从同步的分类
Redis主从同步分为两种类型:
- 全量同步 (FULL RESYNC):初次同步或数据不一致时进行
- 增量同步 (INCREMENTAL RESYNC):后续数据更新时使用
二、全量同步的详细步骤和原理
1. 全量同步触发条件
- 从节点首次连接主节点
- 从节点的replid与主节点不一致
- 从节点请求的offset不在复制积压缓冲区范围内
- 主节点重启导致replid变化
2. 全量同步流程
步骤1:从节点发起连接
- 从节点发送PSYNC命令:
PSYNC ? -1(首次连接时使用)
步骤2:主节点判断同步类型
- 主节点检查从节点发送的replid和offset
- 发现replid不一致(因为从节点是全新的,有自己独立的replid),决定进行全量同步
- 主节点返回响应:
+FULLRESYNC <replid> <offset>
步骤3:主节点生成RDB快照
- 主节点执行
BGSAVE命令,生成RDB快照文件 - 生成过程中,主节点继续处理写请求,将新写操作记录到
repl_baklog(复制积压缓冲区)
步骤4:RDB文件传输
- 主节点将生成的RDB文件发送给从节点
- 从节点接收RDB文件并清空本地数据
步骤5:RDB加载
- 从节点加载RDB文件到内存
- 从节点保存主节点的replid和offset
步骤6:增量数据同步
- 主节点将RDB生成期间的命令从
repl_baklog中发送给从节点 - 从节点执行这些命令,使数据与主节点保持一致
步骤7:后续同步
- 从节点完成初始同步后,主节点持续将新写入的命令发送给从节点
- 从节点执行这些命令,保持数据同步
三、增量同步的原理
1. 增量同步触发条件
- 从节点与主节点的replid一致
- 从节点的offset在主节点的repl_baklog范围内
2. 增量同步流程
步骤1:从节点发送PSYNC命令
- 从节点发送PSYNC命令:
PSYNC <replid> <offset> - 其中replid是主节点的replid,offset是当前已同步的偏移量
步骤2:主节点检查同步条件
- 主节点检查replid是否一致
- 检查offset是否在repl_baklog范围内
- 如果条件满足,返回
+CONTINUE
步骤3:增量数据传输
- 主节点将repl_baklog中从offset开始的命令发送给从节点
- 从节点执行这些命令,更新自己的数据集
步骤4:持续同步
- 从节点持续接收并执行主节点发送的增量命令
- 保持与主节点的数据一致
四、关键机制原理
1. 复制ID (replid) 和偏移量 (offset)
- replid:数据集的唯一标识,每个主节点有唯一的replid
- offset:同步偏移量,随着记录在repl_baklog中的数据增多而增大
- 主节点通过比较replid和offset来判断是否需要全量同步
2. 复制积压缓冲区 (repl_baklog)
- 一个固定大小的环形缓冲区(数组)
- 记录Redis处理过的命令日志及offset
- 保存最近一段时间的写操作,用于增量同步
- 缓冲区大小计算:
缓冲区大小 = 断线时间 × 写入速度
例如:网络可能断开60秒,写入速度1MB/秒 → 缓冲区大小应为60MB
3. PSYNC命令解析
| 场景 | 从节点发送命令 | 主节点响应 | 说明 |
|---|---|---|---|
| 首次连接 | PSYNC ? -1 | +FULLRESYNC | 需要全量同步 |
| 重连 | PSYNC | +CONTINUE | 可以增量同步 |
| 重连 | PSYNC | +FULLRESYNC <new_replid> | 需要全量同步 |
4. 全量同步与增量同步的对比
| 特性 | 全量同步 | 增量同步 |
|---|---|---|
| 触发条件 | 首次连接、replid不匹配、offset超出范围 | replid匹配、offset在缓冲区范围内 |
| 数据传输 | RDB文件(可能很大) | 仅增量命令(较小) |
| 影响 | 主节点fork进程生成RDB,可能造成短暂性能下降 | 仅传输增量命令,影响小 |
| 适用场景 | 初始同步、断线时间过长 | 日常同步 |
五、主从同步的异步性
- 异步复制:主节点不会等待从节点确认,也不会重传丢失的数据
- 优点:低延迟、高吞吐量
- 缺点:数据不一致风险(主节点宕机时,从节点可能丢失部分数据)
- 数据丢失风险:如果主节点宕机,从节点可能丢失最近的写操作
六、复制积压缓冲区的局限性
- 缓冲区大小限制:如果网络断开时间过长,导致repl_baklog中的数据被覆盖
- 无法增量同步:当从节点的offset被覆盖时,无法进行增量同步,必须进行全量同步
- 解决方案:合理设置
repl-backlog-size和repl-backlog-ttl参数
七、从节点的只读模式
- 从节点默认是只读的,可配置
slave-read-only yes - 从节点处理读请求,主节点处理写请求
- 从节点直接写入会导致数据不一致,因此需要设置为只读
八、主从同步的优化建议
-
配置无磁盘复制:
repl-diskless-sync yes- 避免全量同步时的磁盘I/O开销
- 通过网络直接传输RDB文件,无需生成磁盘文件
-
合理设置repl-backlog-size
- 根据业务场景计算:
缓冲区大小 = 断线时间 × 写入速度 - 例如:网络可能断开300秒,写入速度1MB/秒 → 300MB
- 根据业务场景计算:
-
设置repl-backlog-ttl
- 例如:
repl-backlog-ttl 3600(1小时后释放缓冲区)
- 例如:
-
监控主从同步延迟
- 通过
INFO replication查看slave_lag(延迟时间) - 适当调整配置,保证同步延迟在可接受范围内
- 通过
九、总结
Redis主从同步的核心原理是通过replid和offset来判断同步类型,使用repl_baklog作为增量同步的缓冲区。全量同步用于初始同步或数据不一致情况,增量同步用于日常数据更新。主从同步是异步的,具有低延迟和高吞吐量的优点,但也存在数据不一致的风险。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

