主从 offset 差值持续增大说明 repl_backlog_buffer 未兜住增量写入,根因包括从节点拉取慢、断连久或主节点写入猛导致缓冲区被覆盖;需结合写入速率与断连时长估算并合理配置 repl-backlog-size。

主从 offset 差值持续增大,说明 repl_backlog_buffer 没兜住增量写入
Redis 主从复制靠 offset 对齐进度,主节点每写一条命令就推进 master_repl_offset,从节点同步完就更新 slave_repl_offset。两者差值变大,本质是:从节点拉得慢、断连时间长,或主节点写得太猛,导致 repl_backlog_buffer(环形缓冲区)被覆盖。
-
repl_backlog_buffer默认只有 1MB,高写入场景下几秒就刷没;一旦从节点重连时需要的 offset 被覆盖,就只能触发全量同步(PSYNC fullresync) - 查当前积压量:
redis-cli info replication | grep -E "offset|backlog",重点关注repl_backlog_active:1、repl_backlog_size和repl_backlog_histlen - 真正决定能否增量恢复的是
repl_backlog_histlen—— 它代表当前缓冲区里还剩多少字节有效数据,不是看 size
怎么调 repl-backlog-size 才不白调
光加大 repl-backlog-size 不够,必须结合从节点平均断连时长和主节点写入速率估算。设写入速率为 R(B/s),预期最大断连时间为 T(s),那最小 backlog 应 ≥ R × T × 1.2(留 20% 冗余)。
- 例如:主节点平均每秒写入 500KB,从节点网络抖动最长 30 秒,则建议
repl-backlog-size 18000000(≈17MB) - 配置在
redis.conf中,改完需重启或用CONFIG SET repl-backlog-size 18000000(注意:该命令不会持久化到配置文件) - ⚠️ 不能无脑设成 1GB:过大的 backlog 会占用主节点内存,且 Redis 启动时会预分配整块内存,可能触发 OOM
PSYNC 返回 FULLRESYNC 却没触发 bgsave,说明复制积压缓冲区已失效
正常情况下,从节点重连发 PSYNC <runid><offset></offset></runid>,主节点查 offset 是否在 backlog 范围内。如果返回 FULLRESYNC,但主节点日志里没有 Background saving started by pid,大概率是:slave_repl_offset 请求的 offset 已不在 backlog 可覆盖范围内,或主节点 runid 已变更(如主节点重启过)。
- 检查主节点 runid 是否变化:
redis-cli INFO server | grep run_id,对比从节点上次记录的 runid(INFO replication中的master_run_id) - 确认 backlog 是否活跃:
repl_backlog_active:0表示缓冲区根本没启用(比如主节点从未有从节点连接过) - 从节点 log 出现
Connecting to MASTER→ 紧接着MASTER REPLICA sync: receiving streamed RDB,说明走的是全量,不是增量
从节点延迟高 + offset 差值跳变,优先查网络和从节点 CPU
offset 差值不是缓慢增长,而是突然跳几百上千万,往往不是 backlog 太小的问题,而是从节点卡住了——比如磁盘 IO 堵塞(AOF rewrite + RDB save 同时跑)、CPU 满载、或 TCP 接收缓冲区溢出。
- 查从节点负载:
top -p $(pgrep redis),关注 %CPU 和 %MEM;用iostat -x 1看 await 和 %util - 检查是否开启了
no-appendfsync-on-rewrite yes,否则 AOF rewrite 期间 fsync 会被阻塞,拖慢复制命令执行 - 观察
slave_repl_offset是否“停走”:连续几次INFO replication查到它不变,基本锁定从节点处理卡死
repl-backlog-size 狂调。

















