解决JIT Deoptimization,ES插入性能提升7倍

背景描述

ES节点写入到5.7K,会产生比较多的reject,CPU利用率才30%,部分索引延迟在增加。如图所示:

CPU使用率在30%,但是Rejected记录达到8W行

原因分析

写入场景,CPU打不满且出现异常,根据之前Presto的经验,大概率是JVM问题。打下火焰图看下:

可以看到接近35%的CPU在做JIT Deoptimization。

JIT

为了提高热点代码(Hot Spot Code)的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(JIT)。

“热点代码”两类:

  • 被多次调用的方法
  • 被多次执行的循环体 – 尽管编译动作是由循环体所触发的,但编译器依然会以整个方法(而不是单独的循环体)作为编译对象。

编译器根据概率选择一些大多数时候都能提升运行速度的优化手段,当优化的假设不成立,出现“罕见陷阱”(Uncommon Trap)时可以通过逆优化(Deoptimization)退回到解释状态继续执行。而逆优化有参数是可以控制其阈值的,详细原理可以参考Presto遇到的问题:

https://mp.weixin.qq.com/s/OK39zkUj-kJfY6HYixj_Lw

解决方法

所以JVM修改下面参数验证:

1
2
3
-XX:ReservedCodeCacheSize=512M
-XX:PerMethodRecompilationCutoff=10000
-XX:PerBytecodeRecompilationCutoff=10000

线上效果

如下图所示:

写入性能从单节点5.7k/s提升到40k/s,性能提升7倍,而CPU使用率从30%下降到20%,提升了写入上限值。而这个具体能提升多少其实与具体的Case有关,之前测试遇到过逆优化占用90% CPU的情况。

目录

  1. 1. 背景描述
  2. 2. 原因分析
    1. 2.1. JIT
  3. 3. 解决方法
  4. 4. 线上效果