欢迎光临
我们一直在努力

Redis主从-增量同步

一、前言:为什么增量同步是 Redis 高可用的关键?

在 Redis 主从架构中,全量同步(Full Sync)成本高昂——需生成 RDB、传输 GB 级数据、从节点清库重载。
而增量同步(Partial Resynchronization) 则能在网络闪断后秒级恢复,几乎无感知。

这一切,都依赖于 Redis 的 PSYNC 协议(Partial Synchronization)。

本文将深入剖析:
✅ 增量同步的核心机制
✅ PSYNC2 如何跨越主节点重启
✅ 复制积压缓冲区(Backlog)的工作原理
✅ 生产环境配置与调优建议


二、增量同步 vs 全量同步:本质区别

维度全量同步增量同步
数据载体 RDB 快照文件 命令日志(RESP 格式)
传输量 整个数据库(GB 级) 仅缺失命令(KB~MB 级)
触发条件 首次连接 or PSYNC 失败 replid 匹配 + offset 在 backlog 范围内
恢复时间 秒~分钟级 毫秒~秒级
对主影响 高(fork + IO) 极低(仅内存读取)

✅ 增量同步是 Redis 主从复制高效、可靠的核心!


三、增量同步的三大基石

3.1 复制 ID(Replication ID, replid)

  • 主节点启动时生成一个 40 字节的唯一标识(如 a1b2c3…)
  • 从节点首次全量同步后,会记录该 replid
  • 作用:标识“数据来源是否一致”

🔑 关键突破(Redis 4.0+):
主节点将 replid 和 offset 持久化到 RDB 文件末尾!
即使主节点重启,也能恢复旧 replid,支持跨重启的增量同步。

3.2 复制偏移量(Replication Offset)

  • master_repl_offset:主节点已发送的字节数(全局递增)
  • slave_read_repl_offset:从节点已接收的字节数
  • 延迟(lag) = master_offset – slave_offset

📌 offset 是“同步进度”的精确标尺

3.3 复制积压缓冲区(Replication Backlog)

  • 主节点维护一个固定长度的环形缓冲区(默认 1MB)
  • 存储最近执行的写命令(RESP 格式)
  • 结构:

    char *backlog; // 缓冲区指针
    long long backlog_size; // 总大小(如 100MB)
    long long offset; // 当前写入位置(全局 offset)

✅ 只要从节点的 offset 在 [first_byte_offset, current_offset] 范围内 → 可增量同步


四、PSYNC 协议交互流程(Redis 4.0+ PSYNC2)

4.1 从节点发起同步请求

# 断连重连时,携带上次记录的 replid 和 offset
PSYNC a1b2c3d4… 123456

4.2 主节点响应逻辑

4.3 成功响应:+CONTINUE

  • 主节点从 backlog 中定位 offset 对应位置
  • 将后续所有命令流式发送给从节点
  • 从节点直接执行,无需清库

✅ 整个过程无 fork、无磁盘 IO、无数据重建!


五、复制积压缓冲区(Backlog)详解

5.1 工作原理(环形缓冲区)

|—-[已覆盖]—-|———-[有效数据]———-|
^ ^ ^
first_byte_offset current_offset (master_repl_offset)

  • 当写入超过 backlog_size,覆盖最旧数据
  • first_byte_offset = master_repl_offset – backlog_histlen + 1

5.2 关键配置

# 复制积压缓冲区大小(默认 1mb)
repl-backlog-size 100mb

# 是否自动调整(Redis 7+ 支持动态 resize)
# 目前仍需手动配置

💡 如何计算合理大小?

repl-backlog-size > (最大网络中断时间 × 主节点写入吞吐)

例如:

  • 最大容忍中断 5 分钟
  • 写入速度 10 MB/s
    → repl-backlog-size > 5 × 60 × 10 = 3000 MB

六、心跳与 ACK 机制:保障同步可靠性

6.1 从节点定期上报 offset

  • 每秒发送:REPLCONF ACK <current_offset>
  • 主节点据此更新:slave_ack_offset

6.2 主节点用途

  • 计算从节点延迟:lag = master_repl_offset – slave_ack_offset
  • 实现安全写入:

    min-replicas-to-write 1 # 至少 1 个从在线
    min-replicas-max-lag 10 # 延迟 < 10 秒

✅ 避免主节点在网络分区时继续写入(防脑裂)


七、生产环境最佳实践

✅ 配置建议

# 增大 backlog(根据网络稳定性)
repl-backlog-size 500mb

# 启用心跳(默认开启)
repl-ping-replica-period 5

# 设置超时
repl-timeout 60

# 安全写入(可选)
min-replicas-to-write 1
min-replicas-max-lag 10

✅ 监控指标(必看!)

指标命令告警阈值
主从延迟 INFO replication → lag > 30 秒
backlog 使用率 repl_backlog_histlen / repl_backlog_size > 90%
PSYNC 失败次数 日志 grep "Partial resynchronization not accepted" > 0

✅ 故障排查

  • 问题:总是全量同步
    排查:INFO replication 查看 master_replid 是否变化
  • 问题:增量同步后数据不一致
    排查:检查是否有 FLUSHALL、DEBUG 等危险命令

八、增量同步的局限性

场景说明应对方案
主节点 crash + 未持久化 replid Redis < 4.0 会生成新 replid 升级到 Redis 4.0+
从节点 offset 被 backlog 覆盖 网络中断太久 增大 repl-backlog-size
主节点执行 SCRIPT FLUSH 清空 Lua 脚本缓存 避免随意刷新脚本

⚠️ 注意:KEYS *、FLUSHDB 等大命令会瞬间填满 backlog!


九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

赞(0)
未经允许不得转载:171主机测评 » Redis主从-增量同步
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址