repl-backlog-size过小会导致从节点断连重连时无法增量同步而触发全量同步。应按“写入吞吐×断连容忍时间”估算并调大,且需确保repl_backlog_active=1及合理设置repl-backlog-ttl。

repl-backlog-size 设得太小,从节点断连后立刻触发全量同步
Redis 主从复制中,主节点靠 repl-backlog 这个环形缓冲区暂存最近的写命令。从节点断连重连时,如果它想续传的偏移量(master_repl_offset - slave_repl_offset)已超出缓冲区范围,主节点就无法提供增量数据,只能走 PSYNC fullresync ——也就是全量同步。这是最耗资源的操作,尤其在大实例上可能卡主节点几秒到几分钟。
典型现象:INFO replication 里频繁看到 master_repl_offset 和 slave_repl_offset 差值巨大,或日志反复出现 Partial resynchronization not accepted。
- 默认值是
1mb,对多数生产环境完全不够用——哪怕每秒只写 10KB,100 秒就溢出 - 估算公式:缓冲区大小 ≈ 写入吞吐 × 断连容忍时间。例如主节点 QPS 5k、平均命令大小 200B → 每秒约 1MB 写入,若要求断连 5 分钟内不丢增量,则至少要
300mb - 设置后无需重启,执行
CONFIG SET repl-backlog-size 536870912即可(单位字节),但注意:新缓冲区生效前旧数据会丢失,所以最好在低峰期操作
调大 repl-backlog-size 后内存没涨?检查是否启用了 repl-backlog
repl-backlog-size 生效的前提是主节点有从节点连接过(哪怕当前断开)。Redis 不会在没有主从关系时预分配这个缓冲区——这是常被忽略的“假失效”原因。
- 执行
INFO replication,确认输出中有repl_backlog_active:1。如果是0,说明缓冲区根本没启用,调大配置也没用 - 只要有一个从节点成功完成过一次同步(哪怕之后断开),
repl_backlog_active就会变成1,缓冲区才真正分配 - 如果主节点长期无从节点,又想提前预留缓冲区,可以临时起一个从节点连上再断开,触发初始化
repl-backlog-size 和 repl-backlog-ttl 的配合逻辑
缓冲区不是永久存在的。repl-backlog-ttl 控制它在最后一个从节点断开后存活多久(默认 1 小时)。超时后缓冲区释放,下次有从节点连上来再重建——这时如果新从节点需要的偏移量恰好落在刚释放的区间,照样触发全量同步。
- 如果你的从节点经常短时断连(比如网络抖动、滚动升级),把
repl-backlog-ttl调大(如36000秒)比盲目堆repl-backlog-size更有效 - 但注意:
repl-backlog-ttl只影响“空闲期”,不影响缓冲区容量本身;两者要一起看:大容量 + 长存活 = 更高增量同步成功率 - 修改 TTL 同样用
CONFIG SET repl-backlog-ttl 36000,立即生效
监控 repl-backlog 是否真的够用
光看配置值没用,得验证实际运行中缓冲区有没有被持续击穿。关键指标藏在 INFO replication 输出里:
-
repl_backlog_histlen是当前缓冲区有效数据长度(字节),稳定接近repl_backlog_size说明快满了 -
repl_backlog_first_byte_offset是缓冲区起始偏移量,和master_repl_offset相减就是当前可用窗口大小 - 写个简单脚本每分钟采集一次,画个
(master_repl_offset - repl_backlog_first_byte_offset) / repl_backlog_size曲线,超过 90% 就该扩容了
真正难处理的是突发流量——比如缓存穿透导致瞬间写入暴涨,缓冲区在几秒内被冲垮。这种场景下,单靠调大 repl-backlog-size 不够,得结合客户端降级、主从拓扑优化一起做。

















