Jedis的socket内存泄露的这些坑,别说你没遇到过!

本文详细介绍了在业务线上环境中遇到的Jedis导致的Socket内存泄露问题,通过步骤分析了问题的原因,包括Jedis连接池配置、 Commons-Pool的空闲对象驱逐机制以及Finalizer对内存回收的影响。最终,作者强调了不应忽视任何微小问题的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是关于Jedis的socket内存泄露问题排查的分享。

背景

业务线上有N台机器。其中有一台会缓慢的出现Socket内存泄露。具体表现为在jmap时会常常看到如下类排名很靠前。

5: 274623 30757776 java.net.SocksSocketImpl 8: 274621 13181808 java.net.SocketInputStream 9: 274621 13181808 java.net.SocketOutputStream 17: 274621 8787872 java.net.Socket 21: 274668 6592032 java.net.Inet4Address

从占用数量以及内存情况来说。其实完全是可以接受的。但是不能理解的是为什么就单独这台机器占用偏高。其他机器也有一定的数量,但是和这台机器差别较多。

STEP0

这一台机器唯一和别的机器不同的是:

该机器周期性的在本机进程内执行一些数据逻辑。每5分钟调度一次,每次大概执行1分多钟。所以相比其他机器,他的YGC相对会频繁一点。大约10秒左右触发一次。而其他机器大概是1分钟触发一次。

STEP1

既然创建了这么多的socket相关对象。那需要看看是谁在不停的创建。这里可以使用开源的btrace或者其他instrument工具进行运行时监控(PS: 如果对于instrument和agent感兴趣的可以看此文如何开发一款java应用运行时的监控程序https://juejin.im/entry/5bd7f9156fb9a05d185f3a

### JedisCluster 使用中常见问题与解决方法 #### 连接超时或失败 在高并发场景下,可能会遇到连接超时或失败的情况。这通常是因为JedisCluster默认的连接池配置不足以应对大量请求。 为了优化这个问题,可以通过调整`GenericObjectPoolConfig`来增加最大活动对象数(`maxTotal`)以及等待获取连接的最大时间(`maxWaitMillis`): ```java GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxTotal(64); poolConfig.setMaxIdle(10); poolConfig.setMinIdle(5); poolConfig.setMaxWaitMillis(2000L); Set<HostAndPort> jedisClusterNodes = new HashSet<>(); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001)); // 添加其他节点... JedisCluster jc = new JedisCluster(jedisClusterNodes, poolConfig); ``` 上述设置能够有效缓解因资源不足而导致的服务不可达现象[^2]。 #### 节点信息更新延迟 由于JedisCluster会在本地缓存各个Redis实例的信息并维持相应的连接池,因此在网络状况不佳或者集群拓扑发生变化的时候可能出现旧的数据未及时刷新的问题。对于这种情况,建议适当缩短心跳检测的时间间隔以便更快感知到变化;另外也可以通过手动调用`refreshSlotsCache()`强制重新同步最新的槽位分配情况。 ```java jc.getConnectionHandler().getSlotCache().clear(); // 清除现有缓存 jc.refreshSlotsCache(); // 刷新slot映射表 ``` 此操作有助于保持客户端所持有的元数据始终处于最新状态从而减少错误发生几率[^1]。 #### 多键事务处理局限性 值得注意的是,在分布式环境下实现跨多个物理机器间的原子性操作是非常复杂且代价高昂的事情。鉴于这一点,Redis本身仅提供了针对单一服务器内部多条记录的同时修改能力——即所谓的MULTI/EXEC机制。一旦涉及到了不同主机之间的协调,则不再适用此类方式完成一致性保障的任务了[^5]。 如果应用程序确实存在这方面的需求,则需考虑采用诸如两阶段提交协议(Two-phase Commit Protocol)或者其他更高级别的补偿措施来弥补这一缺陷所带来的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值