原因1:ES的新生代配置的太小yong gc频率很高, 1s一次yonggc
解决方案:手动设置新生代、老年代比例 -XX:NewRatio=1
原因2:ES的索引没有配置为高性能写模式( 这个配置立杆见影 )
原因3: skywalking的agent上传JVM状态信息过於频繁导致产生大量的ES request(这个不是主要原因)
解决方案: 修改agent代码,设置JVM上传频率为30s一次
遇到的现象是已经把oap-server的sample比例设置为1%了,可以看到skywalking中追踪的数据很少但是发现ES所占CPU依然很高
查看源码发现,jvm信息是通过单独的grpc接口上传到oapServer的并且是1S收集一次, 1S上传一次如此高频率的收集jvm数据,每一次收集的有多个指标(memory cpu gc)每个指标又根据分钟、小时、天、月更新多个index,就会导致产生大量的UpdateRequest对象假设有50台JVM实例,每上传一次JVM数据产生18个Request就会导致
我这次是直接把1s修改成了30s,重新打包agent部署、重启,查看日志发现发送到ES的Request相对来说是少了一些但昰ES的cpu占用并没有下降很多大概从300%下降至250%左右ES的新生代配置的太小
由于我们是直接用docker起的ES,用的官方的镜像官方镜像用的JDK12,在这个docker容器中jmap jstat並不能用好在ES直接把gclog打印到了文件中,查看gclog才发现yonggc是如此的频繁甚至不到1s一次
后来网上搜了之后才发现,原来CMS 默认的新生代并不是总堆大小的1/3必须显式设置XX:NewRatio才可以。可以参考
于是手动设置XX:NewRatio=1设置了之后发现yonggc频率变成大概6s一次,CPU占用也大概下降至180%左右其实6s一次还是挺頻繁,后续还是需要考虑增加ES的node以及增加内存来分散压力
其实这块儿主要参考了,大家可以直接看这篇博文
由于skywalking是通过template的方式创建index一個一个修改template的配置比较麻烦,我就直接修改了skywalking的代码添加了上面的配置,然后批量删除旧的与日期相关的index(之所以没有全部删除是因为铨部删除的话需要重启agent) 重新打包、部署skywalking-server
再次观察ES的CPU占用情况,已经降到了100%左右至此 ES的CPU优化暂告一段落吧, 由于skywalking对ES的操作实在是太多叻想完全把ES的CPU降下来是不太现实的,只能考虑增加ES机器减小采样频率了