专栏首页Java架构沉思录记一次ES的GC问题

记一次ES的GC问题

优质文章,及时送达

一. 问题背景

在双十一时,有用户反馈推广平台物料列表出现了耗时严重的情况。筛选排序系统出现过耗时严重的情况,根据业务系统的筛选排序慢接口的traceId, 我们分析了一下请求链路上的瓶颈是ES.

二. 问题排查

首选我们在监控平台上确认了一下ES的访问流量,发现流量曲线变化不大,说明不是ES读请求压力突增导致的。

接着我们看了ES的bigdesk监控,发现有不少Full GC,与此同时查看了GC日志,发现日志里有比较频繁的CMS。

然后分析了下日志的内容,发现cms remark这个阶段时间特别长,甚至有3-5s的情况,而且这个阶段是stop the world的,会影响用户线程的工作。

remark如果耗时较长,通常原因是在cms gc已经结束了concurrent-mark步骤后,旧生代的引用关系仍然发生了很多的变化,旧生代的引用关系发生变化的原因主要是:

  • 在这个间隔时间段内,新生代晋升到旧生代的对象比较多;
  • 在这个间隔时间段内,创建出来的对象又比较多,年轻带也是cms的

这个阶段会导致第二次stop the word,该阶段的任务是完成标记整个年老代的所有的存活对象。

这个阶段,重新标记的内存范围是整个堆,包含_young_gen和_old_gen。为什么要扫描新生代呢,因为对于老年代中的对象,如果被新生代中的对象引用,那么就会被视为存活对象,即使新生代的对象已经不可达了,也会使用这些不可达的对象当做cms的“gc root”,来扫描老年代;因此对于老年代来说,引用了老年代中对象的新生代的对象。

也会被老年代视作“GC ROOTS”:当此阶段耗时较长的时候,可以加入参数-XX:+CMSScavengeBeforeRemark,在重新标记之前,先执行一次ygc,回收掉年轻带的对象无用的对象,并将对象放入幸存带或晋升到老年代,这样再进行年轻带扫描时,只需要扫描幸存区的对象即可,一般幸存带非常小,这大大减少了扫描时间

由于之前的预处理阶段是与用户线程并发执行的,这时候可能年轻带的对象对老年代的引用已经发生了很多改变,这个时候,remark阶段要花很多时间处理这些改变,会导致很长stop the word,所以通常CMS尽量运行Final Remark阶段在年轻代是足够干净的时候。

gc root,cms会扫描年轻带中持有老年代对象的引用,如果年轻带有大量引用需要被扫描,会让Remark阶段耗时增加

为什么remark阶段这么长时间?就是一次cms 周期内,并发标记后到remark这个期间jvm堆内存对象变化很大。看了下remark的时间,对应我们的业务日志里就是一大波 es bulk的操作。对应Bigdesk观察,几秒的卡顿基本都出现在一大波 es bulk操作时间吻和。

分析了bulk引起了remark耗时是因为数据流的物料同步时有些地方写的不够好导致的。

三. 解决方案

1、对GC参数的调整

a.增加了CMS回收的线程数

因为我们是32 核的cpu ,cpu 利用率用bigdesk观察还是很低的,

5%左右。-XX:ParallelGCThreads= N

-XX:ParallelCMSThreads= M

调整这2个参数都可以,它们的关系:

ParallelCMSThreads = (ParallelGCThreads + 3)/4)

调整后情况缓解了一些,remark还是有3,4秒的情况。

b.开启了并行remark

 -XX:+CMSParallelRemarkEnabled

c.强制 remark之前开始一次minor gc,从而减少remark阶段扫描年轻代gc root的开销

-XX:+CMSScavengeBeforeRemark

2、对业务场景中bulk操作的调整

部分场景一次bulk 操作就写1条数据或者很少的数据,在业务里修改了代码逻辑,将bulk操作合并写入更多的数据,减少bulk操作IO的操作对CMS GC的影响。

四. 问题总结

1、遇到问题可以借助监控和日志,分析特征帮助快速定位问题

2、有时候出现性能问题,除了考虑技术上的升级,还可以考虑业务上相应的调整,在某些场景业务调整效果可能更佳 ?

本文分享自微信公众号 - Java架构沉思录(code-thinker),作者:大黄

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java面试通关宝典(三)

    前言 在之前的文章《Java面试通关宝典(一)》和《Java面试通关宝典(二)》中,沉思君为大家介绍了部分常见的面试题,涵盖Java基础、web基础和多线程,...

    黄泽杰
  • Spring AOP失效之谜

    什么是AOP 1 AOP(Aspect Oriented Programming),即面向切面编程,其是OOP(Object Oriented Program...

    黄泽杰
  • Spring AOP失效之谜

    AOP(Aspect Oriented Programming),即面向切面编程,其是OOP(Object Oriented Programming,面向对象编...

    黄泽杰
  • 机器学习实践中应避免的七种常见错误

    用户1737318
  • JNI介绍

    JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C+...

    小蚂蚁与大象
  • JVM(2)--一文读懂垃圾回收

    与其他语言相比,例如c/c++,我们都知道,java虚拟机对于程序中产生的垃圾,虚拟机是会自动帮我们进行清除管理的,而像c/c++这些语言平台则需要程序员自己手...

    帅地
  • 【笔记】607- 读《你不知道的 WeakMap》笔记

    原文主要复习了“JavaScript垃圾回收机制”,“Map/WeakMap区别”和“WeakMap 属性和方法”。这很好弥补被我忽视的知识点。 另外,我们可以...

    pingan8787
  • 速递 | 人脸口罩检测数据+模型+代码+在线网页体验,通通都开源了

    众志成城,抗击疫情。首先,我们向在一线抗击疫情的医护人员和各行各业的从业者致敬。祝愿我们早日战胜疫情,早日迎接春暖花开的那一天。

    OpenCV学堂
  • Pug嵌入

    听着music睡
  • Python数据处理(6)-pandas的数据结构

    pandas是本系列后续内容所需要的第三方库,它是基于之前介绍的NumPy构建的,使得Python可以更加简单、方便地完成一系列数据分析工作。 ? 首先,使用下...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券