repl-disable-tcp-nodelay 默认为 yes,启用 Nagle 算法导致主从复制小包延迟达 200ms;高写入场景应设为 no,但需同步检查 repl-backlog-size 是否充足、网络丢包及从节点性能瓶颈。

repl-disable-tcp-nodelay 默认是 yes,但高延迟时它反而成瓶颈
Redis 主从复制延迟高,很多人第一反应是带宽或 CPU 不够,其实 repl-disable-tcp-nodelay 配置常被忽略。它的默认值是 yes,意味着主节点对从节点的复制数据包会启用 Nagle 算法 —— 等待更多数据或超时(通常 200ms)才发包。在小批量、高频写入场景下(比如每秒几百个 SET),这直接导致从节点看到的数据“卡顿”,延迟跳到秒级。
实操建议:
- 确认当前值:
CONFIG GET repl-disable-tcp-nodelay,如果返回["repl-disable-tcp-nodelay","yes"],就该改了 - 临时生效(不重启):
CONFIG SET repl-disable-tcp-nodelay no - 持久化修改:在 redis.conf 中设为
repl-disable-tcp-nodelay no,并确保配置文件被正确加载(CONFIG REWRITE可辅助验证) - 注意:该参数只影响主→从的复制流,不影响客户端连接或 AOF 重写等其他 TCP 流
改完 repl-disable-tcp-nodelay 还有延迟?检查复制积压缓冲区是否溢出
即使禁用 Nagle,如果主节点写入突增,而从节点同步慢(比如磁盘慢、网络抖动),repl-backlog-size 不够大会触发全量同步(即 SYNC),此时延迟会飙升并伴随 Master does not have enough backlog 日志。
判断与调优方法:
- 查当前积压大小:
CONFIG GET repl-backlog-size,默认仅 1MB,对中高流量实例远远不够 - 估算所需大小:按主节点平均每秒写入命令字节数 × 期望容忍的断连时间(秒)。例如每秒写入 500KB,要支持 60 秒断连恢复,至少设为
30000000(30MB) - 动态调整:
CONFIG SET repl-backlog-size 30000000,注意该操作不会清空现有 backlog,但新大小会在下次创建时生效(如从节点重连后) - 监控指标:
redis-cli info replication | grep backlog查看repl_backlog_active、repl_backlog_histlen和repl_backlog_size是否匹配
为什么有些环境设成 no 后延迟反而更不稳定?
禁用 Nagle 虽减少单次延迟,但会显著增加小包数量 —— 在网络本身存在丢包、高延迟或中间设备(如某些云厂商 SLB、防火墙)对小包处理低效时,TCP 重传和 ACK 延迟会被放大,反而造成抖动加剧。
排查路径:
- 对比改配置前后
netstat -s | grep -i "segments retransm"的重传数变化 - 在主从之间抓包(如
tcpdump -i any port 6379 -w repl.pcap),重点观察从节点发出的 ACK 是否滞后、是否存在重复 ACK 或 SACK - 若确认是网络层问题,可暂时回退
repl-disable-tcp-nodelay yes,转而优化网络路径(比如直连替代 SLB、升级网卡驱动、关闭 offloading 特性) - 不要同时调大
repl-backlog-size和激进降低repl-disable-tcp-nodelay,二者叠加可能让内核 socket 发送队列持续满载,引发 write blocking
从节点自身性能不足时,光调主节点参数没用
主节点配置再合理,如果从节点 CPU 持续 >80%、磁盘 I/O wait 高、或开启了 slave-serve-stale-data no + slave-read-only yes 下还承受大量读请求,复制线程会被挤占,延迟自然累积。
关键检查项:
- 运行
INFO replication,看master_last_io_seconds_ago是否持续大于 0(说明从节点已停止收包) - 检查
INFO clients中connected_clients和client_longest_output_list,后者过大表示输出缓冲区堆积(常见于从节点响应慢导致主节点缓存未发送数据) - 确认从节点未开启 AOF +
appendfsync always,这种组合会让每个写命令都刷盘,彻底拖垮同步速度 - 生产环境建议:从节点也部署为专用复制节点(不承接业务读),必要时用
redis-cli --slave-mode验证纯复制吞吐
repl-disable-tcp-nodelay 放进网络链路、积压缓冲、从节点负载这三个维度里交叉验证,而不是单独改一个配置就期待立竿见影。


















