Redis连接数打满,客户端泄漏

Redis 连接数被打满时,服务端会拒绝新的连接请求,客户端报 ERR max number of clients reached,整个业务链路随之变慢甚至不可用。
这类问题最常见的原因有两个:客户端获取连接后没有正确释放,以及服务端 timeout 参数配置不当。
下面按真实故障排查顺序,从确认现状到修复调优逐步操作,手把手带你解决问题。

先确认连接数到底卡在哪一步

登录 Redis 服务器,执行 redis-cli 进入命令行,先看当前连接状态:

redis-cli INFO clients

重点关注 connected_clientsblocked_clients
如果 connected_clients 已经接近或等于配置上限,说明连接池确实被占用完。
再查看最大连接数限制:

redis-cli CONFIG GET maxclients

确认是连接数真的打满后,下一步要弄清楚这些连接是从哪里来的。
如果你的 Redis 没有设置密码,建议先加一层保护,否则外部扫描器很容易通过暴力连接占满连接数。
检查方式:

redis-cli CLIENT LIST

观察输出中的 addr 字段,也就是客户端 IP 和端口。
如果大量连接来自同一个内网应用服务器,那基本可以判定是该应用内存有连接泄漏;
如果来自公网陌生 IP,则要考虑安全策略问题。

定位并修复客户端连接泄漏

客户端连接泄漏通常发生在连接池使用不当的场景。
以 Java 的 Jedis 和 Lettuce 为例,常见错误是每次请求都新建连接,却没有在 finally 块中归还或关闭连接;
或者连接池的 maxTotal 设置过小,高峰时所有连接被借出后等待归还,造成连接积压。

先检查你的连接池配置。
以 JedisPool 为例,核心参数如下:

JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(20);
config.setMinIdle(5);
config.setMaxWaitMillis(3000);

如果应用代码在获取 Jedis 实例后没有放入 try-finally 中归还,连接就会一直被占用。
正确写法:

try (Jedis jedis = pool.getResource()) {
    jedis.set("key", "value");
}

使用 try-with-resources 后,无论正常执行还是抛异常,连接都会自动归还到池中。
如果你用的框架是 Spring Boot 默认的 Lettuce,同样要注意连接池配置,在 application.yml 中开启连接池:

spring:
  redis:
    lettuce:
      pool:
        max-active: 50
        max-idle: 20
        min-idle: 5
        max-wait: 3000ms

排查时还可以借助 CLIENT LIST 输出里的 ageidle 字段。
如果大量连接 age 很大且 idle 也很长,说明这些连接被创建后一直没被复用,基本可以判断为泄漏或池配置不合理。

调整 Redis timeout 参数释放空闲连接

当确认代码层面没有明显泄漏后,
仍然可能因为 timeout 参数设置过大,
导致大量空闲连接长期占用服务端资源。timeout 表示客户端空闲多少秒后,
服务端主动断开连接,
默认值通常是 0,
也就是永不断开。

登录 redis-cli 查看当前值:

redis-cli CONFIG GET timeout

建议将 timeout 设置为 300 秒,同时配合 tcp-keepalive 让服务端主动检测死连接:

redis-cli CONFIG SET timeout 300
redis-cli CONFIG SET tcp-keepalive 60

但注意,CONFIG SET 只对当前实例生效,重启后就会丢失。
要想永久生效,需要修改 redis.conf 文件,找到这两行:

timeout 300
tcp-keepalive 60

如果没有 tcp-keepalive 配置项,直接补充到文件末尾即可。
修改后重启 Redis 服务:

systemctl restart redis

这里有一个容易踩坑的点:timeout 设置过小会导致短连接应用频繁断线,比如某些连接池 idel 检测周期较长,连接被服务端回收后客户端仍在使用,反而引发报错。
所以建议先从 300 开始观察,如果业务允许再逐渐缩短到 120 或 60。
客户端侧的超时配置同样重要,比如 Jedis 的 connectionTimeoutsoTimeout 不要设置过大,否则应用会长时间阻塞等待 Redis 响应。

修改后的验证与日常监控

调优完成后,需要确认连接数是否回归到合理范围。
继续在 redis-cli 中执行:

redis-cli INFO clients

观察 connected_clients 是否明显下降。
想要更直观地观察动态变化,可以开启 Redis 慢查询日志和状态监控:这里推荐使用 redis-cli --stat 实时刷新关键指标:

redis-cli --stat

这个命令会每秒钟输出一次连接数、内存和命中率等数据,非常适合运维排查时观察。
日常监控层面,建议在应用服务器上配置脚本,定期采集 Redis 连接数,当 connected_clients 超过 80% 的 maxclients 时触发告警。

两个容易被忽略的细节

排查过程中还有两个细节经常被忽略。
一是 Redis 的 maxclients 默认值只有 10000(部分发行版可能更小),如果业务并发高,即使没有泄漏也很容易打满,可以根据实际内存和文件句柄数适当调大,比如设置为 20000。
改完后同样要同步到 redis.conf。

二是如果应用和 Redis 之间有负载均衡或代理(如 Twemproxy、Codis),连接打满的根因可能不直接来自业务代码,而是代理层没有正确释放后端连接。
这种情况需要查看代理的日志和连接池配置,不要只盯着 Redis 服务端调参。

遇到 Redis 连接数持续上涨、偶发连接超时报错时,按照本文的排查顺序,先看 CLIENT LIST 定位连接来源,再整改客户端连接池,最后调整服务端 timeouttcp-keepalive,大多数问题都能在半小时内解决。
如果调优后依然异常,建议抓取应用栈信息,确认是否有长时间阻塞的 Redis 调用,再做进一步优化。

分享到:
上一篇
KVM宿主机监控,libvirt_exporter接入
下一篇
Nginx代理出现504 Gateway Timeout
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意