主从延迟过大是系统级瓶颈信号,需先定位卡点再干预:不能只看Seconds_Behind_Master或offset差值,而要结合网络流量、CPU/IO负载、配置参数及客户端路由等全链路排查,区分可接受毛刺与必须修复的架构漏点。

主从延迟过大不是“修一下就能好”的配置问题,而是系统级信号:复制链路某处已出现持续性瓶颈。必须先定位卡点,再针对性干预。
查清延迟到底是网络卡、从节点慢,还是主节点压爆了
别只看 Seconds_Behind_Master(MySQL)或 slave_repl_offset 差值(Redis)——这两个指标只能告诉你“差多少”,不能告诉你“卡在哪”。
- 对 Redis:用
redis-cli -h slave-ip info replication查master_repl_offset和slave_repl_offset,再立刻连主节点执行redis-cli -h master-ip info replication看master_repl_offset;三者差值扩大趋势比瞬时值更重要 - 同时跑
iftop -P 6379:如果主节点出向流量持续打满网卡(比如 >90% 带宽),说明是网络或主节点写入过载;如果从节点入向流量低但 offset 差值还在涨,大概率是从节点解析/执行命令慢 - 检查从节点 CPU 和磁盘 IO:
top看redis-server进程是否长期 100% 占用 CPU;iostat -x 1看%util是否持续 >95%,尤其当await高而svctm低时,说明磁盘在排队
repl-backlog-size 调大 ≠ 延迟下降,但不调大一定会更糟
这个参数只决定“断连后能否做部分同步”,不加速同步本身。但它一旦太小,会触发频繁全量同步,把延迟从“高”变成“跳变式失控”。
- 合理值必须按真实流量算:
峰值写入带宽(B/s) × 断连容忍时长(s) × 1.2;比如实测in=4.8MB/s,允许断连 90 秒 → 至少设为555745280(约 530MB) - 只改
repl-backlog-size没用:必须同步放大client-output-buffer-limit slave(建议设为512mb 128mb 60),否则从节点缓冲区溢出,主节点会主动断连 - 确认
repl-diskless-sync yes已启用,避免主节点bgsave时磁盘 IO 成瓶颈;但前提是**从节点内存充足**,能一次性接收完整 RDB 流
从节点自身处理能力不足的典型表现和应对
当 slave_repl_offset 推进缓慢,且 CPU 或磁盘无明显瓶颈时,问题往往藏在配置或负载上。
-
appendonly yes+appendfsync always是常见陷阱:每条命令都刷盘,slave_repl_offset推进速度直接腰斩;生产环境应设为appendfsync everysec - 从节点被用于离线分析、备份导出等非复制任务:这些操作会抢占 CPU、内存、磁盘 IO,导致复制 SQL 线程饥饿;必须隔离——要么换专用从节点,要么限制其
cpu-quota或ionice - Redis 版本低于 3.2:旧版本从节点不主动删除过期 key,可能读到大量脏数据;升级是硬要求,不能靠业务层兜底
客户端路由策略没生效,所有“优化”都是白忙活
很多团队花大力气调参、加机器,结果发现 90% 的读请求根本没落到从节点上——因为客户端压根没配读副本策略。
- Jedis:别依赖
JedisSentinelPool默认行为,必须显式构造连接池指向本地从节点地址,或改用JedisCluster+ 自定义拦截逻辑 - Lettuce:初始化时必须设置
ClientOptions.builder().readFrom(ReadFrom.REPLICA_PREFERRED),否则默认只连主节点 - ioredis(Node.js):启用
scaleReads: 'slave'后,还要配合 DNS 或服务发现过滤掉跨机房从节点,否则可能路由到高延迟远端 - 关键验证方式:在从节点上执行
CLIENT LIST,确认有活跃连接来自业务 IP,且flags字段含r(表示只读)
真正难的从来不是“怎么调参数”,而是区分清楚:哪些延迟是业务可接受的毛刺,哪些是架构层必须堵住的漏点。比如用户刚下单后查订单列表,必须强一致;但首页商品推荐位缓存过期 2 秒,完全可忽略。混为一谈只会让方案越来越重,维护成本越来越高。


















