背景描述
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 | -XX:ReservedCodeCacheSize=512M |
线上效果
如下图所示:
写入性能从单节点5.7k/s提升到40k/s,性能提升7倍,而CPU使用率从30%下降到20%,提升了写入上限值。而这个具体能提升多少其实与具体的Case有关,之前测试遇到过逆优化占用90% CPU的情况。