repl-backlog-size过小是主库高并发下触发全量同步的唯一技术原因;需按峰值写入速率×最长断连时间×1.4计算,确保repl_backlog_active=1且master_repl_offset−slave_repl_offset≤repl_backlog_size,并重建主从连接方可生效。

直接结论:repl-backlog-size 不够大,是主库高并发写入下触发全量同步的唯一技术原因;调大它就能解决,但必须算准、配对、重建连接。
怎么确认是 repl-backlog-size 导致的溢出
不是看延迟、不是看网络抖动,而是盯住三处输出:
- 执行
INFO replication,检查repl_backlog_active是否为 1(为 0 表示缓冲区根本没启用) - 观察日志是否频繁出现
Partial resynchronization not possible (no cached master) - 对比
master_repl_offset和从节点上报的slave_repl_offset差值——如果该差值长期 >repl_backlog_size,说明旧 offset 已被覆盖
如何计算安全的 repl-backlog-size 值
公式不是“平均写入 × 平均断连”,而是按最坏情况推演:
- 用
redis-cli --latency-history -i 1抓 95% 分位的网络毛刺持续时间(比如 112 秒),这就是你要容忍的最长断连时间 - 从
INFO commandstats中提取高频写命令(如cmdstat_set、cmdstat_hset)的calls和usec_per_call,结合业务 key/value 大小估算单次命令平均字节数(例如 SET 命令含协议开销约 280 字节) - 峰值写入速率 = 高频命令每秒调用次数 × 单次平均字节数(注意不是 QPS,是字节/秒)
- 最终值 = 峰值字节/秒 × 最长断连秒数 × 1.4(留 40% 余量),单位换算成字节后填入配置
CONFIG SET 后为什么没生效
调大 repl-backlog-size 后,repl_backlog_histlen 不涨、内存不增加、从节点依然全量同步——这不是配置失败,而是机制限制:
-
CONFIG SET repl-backlog-size 536870912立即生效,但只影响后续新建的复制连接 - 已存在的主从链路继续使用旧缓冲区,不会扩容,也不会重新分配内存
- 缓冲区只有在至少一个从节点完成过一次完整同步后才会被初始化(哪怕它当前已断开);若
repl_backlog_active为 0,需先起一个临时从节点连上并完成同步,再断开 - 所有从节点必须重建连接:依次执行
REPLICAOF no one→REPLICAOF,否则永远用不上新缓冲区
容易被忽略的细节
多个从节点时,不能按平均断连时间算,必须取历史中最长那个;缓冲区大小和主节点内存压力无直接关系(它是固定大小的环形 buffer,不随数据增长),但过小会导致频繁全量同步,间接拉高主节点 CPU 和磁盘 IO;真正危险的是「你以为调大了,其实连接没重建」——这会让问题持续存在,直到某次抖动再次打穿缓冲区。











