主从复制延迟持续扩大是同步链路某环节卡死或失衡所致,常见原因包括repl-backlog-size溢出、fork阻塞、网络小包风暴及从节点处理能力不足,需逐项排查而非单一调参。

主从复制延迟持续扩大,不是“慢慢变差”,而是某个环节已经卡死或失衡——常见原因集中在 repl-backlog-size 溢出、fork 阻塞、网络小包风暴、从节点处理能力不足这四类,调优必须逐项排除,不能只改一个参数就指望见效。
为什么 master_repl_offset 和 slave_repl_offset 差值越拉越大
这不是“同步慢”,而是同步链路中某处持续积压,导致从节点永远追不上。典型现象是 INFO replication 中 lag 字段稳定在 1–5 秒以上,且 repl_backlog_histlen 长期等于 repl_backlog_size(缓冲区满载)。
- 主节点
fork耗时过长(比如内存 32GB 实例fork耗时 >1s),期间写命令无法写入复制缓冲区,直接丢弃或触发 backlog 溢出 - 从节点开启
appendonly yes且appendfsync always,每条命令都刷盘,slave_repl_offset推进速度远低于主节点写入速度 - 网络层大量
PSH, ACK小包(tcpdump -i any port 6379 | grep "PSH\|ACK"可验证),说明repl-disable-tcp-nodelay no在高吞吐下反而加剧抖动 - 从节点 CPU 持续 >90% 或磁盘 iowait 高,
redis-cli --stat显示in=流量正常但out=持续偏低,说明数据卡在从节点接收/解析阶段
调大 repl-backlog-size 后延迟反而更明显
盲目调大 repl-backlog-size 不仅无效,还可能掩盖真实瓶颈。它只是个环形缓冲区,不加速传输也不提升执行,只决定“断连后还能不能做部分同步”。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 如果实际写入带宽是 8MB/s,设
repl-backlog-size 4gb(≈500秒缓冲),但网络 RTT 高达 40ms 且丢包率 >0.5%,从节点根本收不全数据,缓冲区再大也白搭 -
repl-backlog-size增大后,必须同步放大client-output-buffer-limit slave,否则主节点会因从节点缓冲区溢出主动断连——错误日志里会出现Client id=xxx addr=xxx:xxx exceeded output buffer limits - 计算公式要基于实测峰值:用
redis-cli -h <master> --stat</master>观察连续 10 秒最高in=值(单位 KB/s),乘以容忍断连时长(如 120 秒)再 ×1.2,结果转为字节填入配置。例如:峰值 5242880 B/s × 120 × 1.2 = 754974720 ≈ 755MB - 设完立刻执行
CONFIG SET repl-backlog-size 754974720,并确认CONFIG GET repl-backlog-size返回值一致,否则重启失效
repl-disable-tcp-nodelay 该开还是该关
这个开关的效果高度依赖网络质量,不是“开就低延迟”或“关就高吞吐”,而是权衡小包延迟 vs 合并等待。
- 跨机房或公网部署(RTT >10ms)、写入稀疏(QPS no(即启用 NODELAY)更稳妥
- 同机房万兆网、写入密集(QPS >5k)、且观察到
netstat -s | grep "segments retransmitted"重传率 >0.1%,可尝试设为yes,但必须配合tcp_slow_start_after_idle=0系统级调优 - 修改后验证不能只看 offset 差值:用
redis-cli -r 10 -i 1 INFO replication | grep lag观察lag字段波动范围是否收窄;同时抓包确认 PSH 包数量下降 60% 以上才算生效 - 切忌在未监控的情况下全局开启:某些旧内核(如 3.10.0-957)开启后反而因 TCP 栈 bug 导致 ACK 延迟激增
真正卡住同步进度的,往往是被忽略的从节点配置
很多人盯着主节点调参,却忘了从节点才是最终执行者。以下几项不检查,主节点再优化也白费。
-
slave-read-only yes必须为yes,否则从节点误写会导致复制流静默中断(旧版本 Redis 不报错) -
replica-serve-stale-data设为no时,从节点一旦检测到延迟超标,会直接拒绝客户端读请求——此时看到的“延迟大”,其实是服务主动降级,而非同步真慢 - 若使用级联复制(master → replica-A → replica-B),中间节点
replica-A的repl-timeout必须大于上游(如设为 90),否则一次抖动会引发雪崩式断连重同步 - 禁用
repl-diskless-sync yes:大 RDB 场景下无盘同步易因 TCP 缓冲区满而中断,反而比磁盘同步更不稳定;优先确保主节点磁盘 IOPS 充足
最常被跳过的动作是:改完参数后没等 30 秒就去查 lag,或者只在一个从节点上验证。延迟问题必须在所有从节点上分别监控 slave_repl_offset 差值趋势,且至少观察 2 个完整心跳周期(默认 repl-ping-slave-period 10 秒)才能判断是否真实收敛。










