Redis client 链接池配置不当引起的频繁 full gc

栏目: 数据库 · 发布时间: 6年前

现象

笔者负责的一个RPC服务就是简单的从Redis Cluster中读取数据,然后返回给上游。理论上该服务的对象大部分都应该是朝生夕死的,但是笔者查看gc log 的时候发现 age >=2 的对象还真有不少,甚至和age=1的对象差不多 。也就是说对象从eden晋升到 Survivor,之后的每次young gc 这些对象都是在 Survivor区域中移动,直到晋升到old 区域中。GC log 如下

Redis client 链接池配置不当引起的频繁 full gc

解决过程

因为只需要查看 Survivor中区域的对象,使用JVM自带的命令就不太合适。 笔者推荐用 唯品会开发 vjmap(他只支持CMS不支持G1) ,他能查看各个age的对象。笔者使用它查看age>=2的堆栈,堆内对象分布如下:

Redis client 链接池配置不当引起的频繁 full gc

其中最令人奇怪的就是deps.redis.clients.jedis.Jedis这个对象。因为这是链接Redis Cluster的对象,理论上 只要流量没有大的波动不会有大量的创建活动 。而且Jedis本身会持有 Sokect、OutputStream、byte[ ]等对象。

笔者找到了创建Jedis对象的地方进行埋点, 发现基本上每六分钟就会销毁和创建一批Jedis对象。因为知道Redis client 采用的是链接池的方式,就是看了一下GenericObjectPool代码,发现 有个定时任务检测对象。关键代码如下:

Redis client 链接池配置不当引起的频繁 full gc

Redis client 链接池配置不当引起的频繁 full gc

Redis client 链接池配置不当引起的频繁 full gc

Redis client 链接池配置不当引起的频繁 full gc

从上面代码我们看出,每隔一段时间,就是检测对象池里面对象,要是发现对象空闲时间超过一定时间,就会强制回收;然后又发现链接少于minIdle了,开始创建对象,以满足mindle。笔者所在公司封装Redis client 设置的检测轮询时间为6分钟。

上面问题已经找到了,解决就比较简单了。因为配置的 mindle过大导致,导致链接池里有大量空闲。项目中配置的mindle为32,修改为3测试 上线 观察。之后gc log如下:

Redis client 链接池配置不当引起的频繁 full gc

Redis client 链接池配置不当引起的频繁 full gc

Redis client 链接池配置不当引起的频繁 full gc

上图中dx04是优化之后的,dx03是优化之前的,从图中我们可以看出f ull gc次数由一周20次降为一周4次, young gc的时间平均下降了1.5ms左右(毕竟能减少对象在 Survivor中的移动

总结

作为项目的ower,我们一定要清楚了解业务特征。看看gc log是否符合业务特征应该呈现的gc log。如果不符合,使用合适的 工具 是查找原因,你一定有所收获。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

与机器赛跑

与机器赛跑

[美]埃里克·布林约尔松(Erik Brynjolfsson)、[美]安德鲁·麦卡菲(Andrew McAfee) / 闾佳 / 2013-1-20 / 6.00

一场数字革命正在加速进行。 一些科幻小说里的场景已经在现实中发生:无人驾驶汽车开上了公路;智能设备能高效地翻译人类语言;人工智能系统在智力竞赛里击败了所有人类选手;工厂雇主开始购买更多的新机器,却不招新工人…… 这些例子都证明,数字技术正在快速地掌握原本只属于人类的技能,并深刻地影响了经济。虽然大多数影响是积极的:数字革新将提高效率、降低商品价格(甚至到免费),以及增加经济总量。 ......一起来看看 《与机器赛跑》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具