Elasticsearch调优记录

1.背景

部署Elasticsearch服务,主要提供记录用户登录日志、访问日志,统计,查询等功能。

遇到的问题为:

  • 平稳运行时CPU使用率为20%左右,当批量更新定时任务执行时,

           CPU使用率激增到60%左右,最高值到达90%,服务器监控系统开始报警。

  •  Elasticsearch长时间运行,内存占用率大幅提高,严重影响功能使用,需要在内存占用较大时重启ES服务。

2.定位CPU使用率高问题以及解决办法

Elasticsearch是基于java开发的,先查看elasticsearch进程的运行情况,然后查看jvm相关参数。生产环境问题已解决(部分问题暂时无法提供截图说明)

1.定位到具体问题

使用jstat -gcutil pid 1000 命令查看垃圾回收情况

可知每两秒进行一次minor GC,定位问题为频繁的minor GC 引起的cpu使用率居高不下。

2.查看垃圾回收器和内存分配情况

1.确定垃圾回收器的使用

生产环境使用jdk版本为jdk11,jvm.options文件中相关参数表明

Elasticsearch调优记录

 

在jdk8-13默认使用的垃圾回收算法为CMS,因为CMS为老年代垃圾收集器,默认与之配合使用的新生代垃圾回收器为ParNew。

使用jps命令找到ES运行的进程id

使用jinfo命令 查看jvm的相关参数,确认使用的垃圾回收器为ParNew+CMS。

Elasticsearch调优记录

 

 2.查看heap大小分配情况

服务器内存为16g,根据官方推荐heap大小配置不宜超过8g

jvm.options配置参数为

-Xmx7g

-Xms7g

没有显示声明新生代的大小,CMS垃圾回收器新生代默认大小为:

max_heap/(NewRatio+1)和ScaleForWordSize(young_gen_per_worker * parallel_gc_threads) 中最小的值。

max_heap/(NewRatio+1)   即最大堆内存/(2+1)  (未显式设置参数NewRatio 则默认为2)  7*1024/3=2389.33M

ScaleForWordSize(young_gen_per_worker * parallel_gc_threads)  计算公式为 young_gen_per_worker * parallel_gc_threads * 13/10

 young_gen_per_worker 的值x86机器为64M,parallel_gc_threads简单的理解为cpu核数8   64*8*13/10=665M

即最后的新生代大小为665M

使用jstat -gc 查看内存分配情况 新生代为665M,

默认参数-XX:SurvivorRatio=8 即Eden:S0:S1=8:1:1 可知Eden内存大小为532M 

可知新生代内存设置太小,Eden区满了之后会进行频繁的minor GC导致Cpu占用率提高

3.解决办法

1.显式设置参数-Xmn    由于老年代占用比例较小,且在minor GC 过程中晋升到老年代的对象较少,所以可以提高新生代的内存占比设置为-Xmn4g

2.改用G1垃圾回收器,可在垃圾回收过程中根据使用情况动态改变新生代的大小

 

3.定位Elasticsearch长时间运行,内存占用率高问题以及解决办法

CMS会在垃圾回收过程中产生内存碎片,不利于程序的长时间运行。

而G1在运行期间不会产生内存碎片,有利于程序长时间运行。

综上所述,从两个方面来看以及生产环境的试运行情况来看,选择修改垃圾回收器为G1的解决方案。

Elasticsearch调优记录

 

 

总结,修改垃圾回收器为G1后,平稳期cpu使用率稳定在5%以下。

 

上一篇:垃圾收集器


下一篇:最佳加法表达式