Redis主从复制断连根源在客户端连接异常或主从链路中断;需调大repl-timeout(建议300)、client-output-buffer-limit,并确保logfile和loglevel配置生效,同时排查Jedis连接池耗尽等问题。

Redis主从复制本身不使用“连接池”——断开报错真正源头是客户端(如Jedis/Lettuce)与主节点或从节点建立的TCP连接异常,或是主从之间复制链路自身中断。所谓“连接池断开”,90%以上实际是客户端拿不到可用连接、连接被服务端主动关闭、或主从同步链路频繁重连导致的级联故障。
repl-timeout设太小,抖动就全量同步
主从心跳靠 REPLCONF ACK 维持,默认 repl-timeout 60,意味着主节点等 60 秒没收到从节点确认就断连。但网络抖动 + 主节点 bgsave 耗时长(比如 40 秒)+ 从节点处理延迟,很容易突破这个阈值。
- 查当前值:
CONFIG GET repl-timeout,生产环境建议至少设为300(5 分钟),大实例可到600 - 别只改主节点:从节点也需同步调整(虽不直用该参数,但影响其发送
ACK的节奏) - 配套调
repl-ping-replica-period(默认 10 秒),确保心跳频率明显小于repl-timeout,避免丢一次心跳就超时 - 紧急生效命令:
CONFIG SET repl-timeout 300,无需重启
client-output-buffer-limit触发强制断连
主节点为每个从节点维护一个输出缓冲区,用来暂存待同步的增量命令。一旦缓冲区溢出(比如从节点卡住、网络吞吐不足),主节点会直接 close 连接,日志里出现 Client id=xxx has pending output buffer bigger than limit。
- 默认限值是
slave 256mb 64mb 60:硬上限 256MB,软上限 64MB 持续 60 秒即断 - 对跨机房/高延迟链路,必须放宽:比如
CONFIG SET client-output-buffer-limit "slave 1024mb 512mb 120" - 注意单位是字节,
1024mb= 1024 × 1024 × 1024,别写成1g(Redis 不识别) - 该配置只作用于 slave 类型连接,不影响普通客户端
从节点日志为空?先确认 redis.conf 的 logfile 是否生效
很多排查卡在第一步:根本看不到断连原因。因为 Redis 默认 logfile "",等于完全不写日志。
- 运行
CONFIG GET logfile,返回空字符串就说明日志关闭 - 必须同时配两项:
logfile /var/log/redis/redis-server.log+loglevel notice(调试时可临时verbose) - 配完 reload:
kill -SIGUSR1 $(pidof redis-server),不用重启 - 立刻
tail -f /var/log/redis/redis-server.log,看是否滚动出MASTER REPLICA sync started或Connection lost
Jedis 连接池打满导致“假性断连”
应用侧报 JedisConnectionException: Could not get a resource from the pool,常被误判为 Redis 服务问题,实则是客户端连接池耗尽。
- 检查监控中
connected_clients是否接近maxclients(默认 10000),若远低于该值,问题在客户端 - Jedis 默认
maxTotal=8,高并发场景极易打满;Lettuce 基于 Netty,单连接多路复用,更抗压 - 调大池子只是缓兵之计,重点查泄漏:是否有未
close()的Jedis实例?是否在 try-with-resources 外手动获取又忘记归还? - 加监控:暴露
numActive、numIdle、numWaiters指标,告警numWaiters > 0持续 30 秒
真正难调的不是单个参数,而是多个机制的耦合:比如 repl-timeout 小 + client-output-buffer-limit 紧 + 从节点 CPU 高,三者叠加会让断连从偶发变成规律性风暴。每次调参后,务必观察 INFO replication 中的 master_link_status、slave_repl_offset 和 master_last_io_seconds_ago 三个字段的变化节奏,比单纯看日志更早发现问题苗头。











