真实高延迟需同时满足:lag值仅反映心跳间隔,不等于复制延迟;master_repl_offset与slave_repl_offset差值持续扩大且超50mb或>10秒;master_sync_in_progress为0(排除全量同步干扰)。

怎么看延迟是否真的高?别只盯 lag 字段
直接执行 redis-cli info replication,重点看三处:一是 lag 值(它只是心跳间隔,lag=3 不等于延迟 3 秒);二是 master_repl_offset - slave_repl_offset 的差值,超过 50MB 或持续增长 >10 秒,才算真实高延迟;三是 master_sync_in_progress 是否为 1,如果是,说明正在全量同步,此时所有偏移量指标都失真。
常见误判:看到 lag=5 就 panic,但实际偏移差才 2000 —— 这是正常心跳延迟,不是复制滞后。真正要算的是字节级偏移差,再结合写入速率估算秒级延迟(比如每秒写入 1MB,差 50MB ≈ 50 秒延迟)。
repl-disable-tcp-nodelay 设成 no 后延迟反而抖动?先查重传
这个参数默认是 yes,启用 Nagle 算法,小包攒 200ms 才发,在高频写场景下就是瓶颈。设成 no 后延迟下降明显,但若网络本身丢包或中间设备(如云厂商 SLB、防火墙)对大量小包处理低效,TCP 重传会激增,导致延迟抖动甚至恶化。
- 改前改后都运行:
netstat -s | grep -i "segments retransm",重传数翻倍?说明网络层扛不住 - 主从间抓包:
tcpdump -i any port 6379 -w repl.pcap,用 Wireshark 看从节点发的 ACK 是否滞后、是否有重复 ACK 或 SACK - 如果确认是网络问题,暂时回退
repl-disable-tcp-nodelay yes,转而优化路径(比如换直连网卡、绕过中间负载均衡器)
repl-backlog-size 不够会触发全量同步,但改了也不生效?注意生效时机
CONFIG SET repl-backlog-size 60000000 是动态设置,但它不会清空现有 backlog,新大小只在下次创建时生效 —— 比如从节点断连重连、或主节点重启后重建 backlog。所以改完看不到效果,很可能是旧 backlog 还在用。
验证方式:redis-cli info replication | grep repl_backlog,关注 repl_backlog_active(是否启用)、repl_backlog_histlen(当前已用长度)、repl_backlog_size(配置值)三者是否匹配。若 histlen 长期接近 size,且日志里出现 Master does not have enough backlog,就说明溢出了。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
估算公式:所需大小 = 平均每秒写入字节数 × 最大容忍断连时间 × 安全系数(1.5–2)。例如写入 8MB/s,要支持 45 秒断连恢复,至少设为 repl-backlog-size 54000000(约 54MB)。
从节点同步慢,不一定是 CPU 或磁盘问题,先看 client-output-buffer-limit
从节点接收复制流时,数据先存进输出缓冲区,再逐步回写。如果这个缓冲区太小,主节点会强制断开连接,触发重连和潜在全量同步 —— 表象就是延迟飙升、反复重连。
client-output-buffer-limit slave 默认是 256mb 64mb 60(硬限制 256MB,软限制 64MB,超限 60 秒断连)。写入突增时,64MB 很快打满。
- 临时调大:
CONFIG SET client-output-buffer-limit "slave 1024mb 256mb 120" - 持久化修改:在
redis.conf中写明,避免重启后还原 - 监控项:
redis-cli info clients | grep output_buffer,看client_longest_output_list和client_biggest_input_buf是否逼近阈值
真正容易被忽略的是:这个缓冲区限制的是“待发送给从节点的数据”,不是从节点本地处理能力。即使从节点磁盘 I/O 很好,只要主节点发得太快、从节点消费不及,缓冲区照样溢出 —— 所以调参要结合主节点写入节奏和从节点同步吞吐一起看。










