随着项目数据持续不断增长,在触发老年代GC内存回收时,暂停查询或搜索致使业务请求等待过长导致业务订单超时。

问题分析

内存分区简单介绍:

新生代Eden区(存放新创建的对象)满时,就会触发Minor GC(也称Young GC)
新生代Survivor区(存放已经经过一次垃圾回收的对象)
老年代old区(存放已经存活了一段时间的对象的区域)满时,则会触发Full GC(也称Old GC)

通过不断对测试环境压力测试,模拟生产环境遇到的报错信息。

# 测试环境日志
[2023-04-29T17:40:55,304][WARN ][o.e.m.j.JvmGcMonitorService] [node-3] [gc][young][408][152] duration [1.2s], collections [1]/[2.5s], total [1.2s]/[4.5s], memory [434.1mb]->[352.4mb]/[990.7mb], all_pools {[young] [160.1mb]->[41.8mb]/[266.2mb]}{[survivor] [16.5mb]->[33.2mb]/[33.2mb]}{[old] [257.4mb]->[277.3mb]/[691.2mb]}

分析日志:

  • 时间戳:2023-04-29T17:40:55,304
  • 日志级别:WARN
  • 类名:o.e.m.j.JvmGcMonitorService
  • 节点名称:node-3
  • GC类型:young
  • GC耗时:1.2s
  • GC时间占比:collections [1]/[2.5s]
  • GC总耗时:total [1.2s]/[4.5s]
  • 内存使用情况:memory [434.1mb]->[352.4mb]/[990.7mb]
  • 内存池使用情况:

    • young generation (eden) [160.1mb]->[41.8mb]/[266.2mb]
    • survivor [16.5mb]->[33.2mb]/[33.2mb]
    • old generation [257.4mb]->[277.3mb]/[691.2mb]

通过分析日志,可以看到这次GC总共耗时4.5s,其中young耗时2.5s。

解决办法

提高新生代内存大小,避免在高业务并发时,因频繁GC导致老年代内存过早回收。
新生代内存适合配置的大小约为总堆内存的三分之一。通常新生代内存为堆内存的三分之一。

# 指定堆内存大小
-Xms12g
-Xmx12g
# 指定初生代初始大小
-XX:NewSize=4g
# 指定初生代最大大小
-XX:MaxNewSize=4g
-XX:+UseConcMarkSweepGC
# 启用CMS并行标记(默认开启)
-XX:+CMSParallelRemarkEnabled
# 启用CMS多线程收集(默认开启)
-XX:+CMSConcurrentMTEnabled
# 只使用CMS垃圾回收器来触发垃圾回收。(默认开启)
-XX:+UseCMSInitiatingOccupancyOnly
# 当CMS垃圾回收器老年代使用的堆达到70%时,触发CMS垃圾回收器。
-XX:CMSInitiatingOccupancyFraction=70
检查配置修改结果

在重启ES服务后,可以通过访问以下地址,查看是否生效。

curl -XGET 'http://localhost:9200/_nodes?filter_path=**.jvm.options' | jq '.nodes[].jvm.options'

可以通过以下接口查看GC次数。

http://192.168.230.201:9200/_nodes/stats?filter_path=**.gc
END

本文标题:Elasticsearch6.4优化JVM参数解决GC超时问题

本文作者:宇宙最帅的男人

本文链接:https://lolicp.com/elasticsearch/202304579.html

版权声明:转载或者引用本文内容请注明来源及原作者,本文著作权归作者 (宇宙最帅的男人) 所有。

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

最后修改:2024 年 02 月 08 日
如果觉得我的文章对你有用,请随意赞赏