性能文章>我司基础组件更新本地缓存策略问题导致young gc时间升高>

我司基础组件更新本地缓存策略问题导致young gc时间升高原创

1年前
738045

背景

有次想研究一下服务QPS和young gc的时间的关系。假如服务对外提供的接口的平均响应时间是1s,那么最坏情况下该请求用到的对象就应该存活1s(为什么是最坏,因为很多中间变量不需要这么存活这么久)。如果QPS由100升高到200,那么在1s之内存活的对象应该要翻倍,那么在young gc的时候copy时间基本上也要翻倍,root 扫描阶段应该会稍微的升高但是应该不明显。带着这样的假设去看了服务的高峰期和低峰期young gc时间,发现基本上没啥变化。young gc meantime如下图:

image.png

问题追踪过程

于是去看了一下gc log,不管是在业务高峰期还是低峰期,每次从eden区域中晋升到survivor区域中的对象大小都差不多,并且再次young gc的时候这些对象就会释放。gc log 如下:

image.png

于是先用gdb 去dump了下来survivor区域中的内容,发现了异常点。survivor区域里面有MCC(我司的配置中心)的内容。理论上只要配置中心没有变化,这些值早点应该进入到了old区域啊,不可能在survivor区域。内容如下:

image.png

为什么防止误判,我过一段时间就重新dump下内容发现每次都有,有时候会有两份MCC的内容。肯定确定MCC有问题。于是向MCC的人反馈有问题,但是MCC人坚持认为没有问题,他们认为这是定时拉取动作应该有的表现(PS:我觉得他们对于GC这块理解可能有点问题才会认为没有问题)。

之后有事比较忙,这个事情就放下了。前一段时间有时间就重新看了一下这个问题,用vjmap去看了一下survivor区域的内容,发现里面包含大量基础组件的内容不仅仅是MCC,服务依赖的下游服务节点数据都在survivor中存活。对象如下图:

image.png

SGService、SGServiceDetail都是基础组件的对象,并且SGService里面包含大量的map,String等信息。

于是我就翻看了他们这一块相关的代码,很快就发现了问题。发现他们有个定时拉取的从agent拉取对象的定时任务,拉取之后全量更新本地缓存。代码如下:

image.png

image.png

其中reload方法就是从agent上获取拉取实时数据,从agent拿到对象之后直接替换了cache里面的内容,就会导致每次从agent获取的对象都会生存5s,young gc的时候存活下来,copy阶段时间会延长;特别在依赖的下游服务机器比较多的时候。

我自己把他们这个定时任务给去掉,重新上线测试了一下,young gc 时间提升还是很明显的,监控如下:

image.png

昨天刚好群里也说到基础组件可能有问题的事,我就把这个问题给抛出来了,终于基础组件相关人联系我了并且确认了问题的存在他们需要评估一下修正一下。

总结

在做定时拉取数据的时候,一定要先diff,只有不同的时候在再替换,不要直接以最新的数据替换老的数据。

但是QPS和young gc 时间的关系还没有研究清楚呢。

请先登录,查看4条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

字符串字面量长度是有限制的
前言 偶然在一次单元测试中写了一个非常长的字符串字面量。 正文 在一次单元测试中,我写了一个很长的字符串字面量,大概10万个字符左右,编译时,编译器给出了异常告警 `java: constant
多次字符串相加一定要用StringBuilder而不用-吗?
今天在写一个读取Java class File并进行分析的Demo时,偶然发现了下面这个场景(基于oracle jdk 1.8.0_144): ``` package test; public c
如何通过反射获得方法的真实参数名(以及扩展研究)
前段时间,在做一个小的工程时,遇到了需要通过反射获得方法真实参数名的场景,在这里我遇到了一些小小的问题,后来在部门老大的指导下,我解决了这个问题。通过解决这个问题,附带着我了解到了很多新的知识,我觉得
JVM源码分析之String.intern()导致的YGC不断变长
概述之所以想写这篇文章,是因为YGC过程对我们来说太过于黑盒,如果对YGC过程不是很熟悉,这类问题基本很难定位,我们就算开了GC日志,也最多能看到类似下面的日志`[GC (Allocation Fai
高吞吐、低延迟 Java 应用的 GC 优化实践
本篇原文作者是 LinkedIn 的 Swapnil Ghike,这篇文章讲述了 LinkedIn 的 Feed 产品的 GC 优化过程,虽然文章写作于 April 8, 2014,但其中的很多内容和
「每日五分钟,玩转 JVM」:久识你名,初居我心
聊聊 JVMJVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别。JVM可以说和我们是老朋友了
据说99.99%的人都会答错的类加载的问题
概述首先还是把问题抛给大家,这个问题也是我厂同学在做一个性能分析产品的时候碰到的一个问题。 同一个类加载器对象是否可以加载同一个类文件多次并且得到多个Class对象而都可以被java层使用吗请仔细注意
Java多线程——并发测试
编写并发程序时候,可以采取和串行程序相同的编程方式。唯一的难点在于,并发程序存在不确定性,这种不确定性会令程序出错的地方远比串行程序多,出现的方式也没有固定规则。那么如何在测试中,尽可能的暴露出这些问