一次ElasticSearch集群jvm占用高的排查解决过程

目录

一、问题现象

二、问题排查过程

1、查看flink日志

2、查看es集群日志

3、ES集群jvm内存占用分析

4、jvm的GC 占比分析

5、jvm dump文件分析

三、总结


一、问题现象

项目上使用flink将实时数据写入ES,随着每天数据的逐渐增多,最近出现flink程序经常性挂掉的现象,导致数据出现积压和延迟。

二、问题排查过程

1、查看flink日志

     首先查看flink任务的运行状态和日志,发现flink的CheckPoint失败频繁,一旦失败的次数达到指定的值任务就会重启,短时间内任务频繁重启,如下图所示:

通过flink任务的背压分析,发现是写入ES超时失败导致的,排查ES集群所在的服务器cpu负载、内存使用、磁盘和网络负载,发现均正常。

2、查看es集群日志

继续查看es节点的日志,发现下面的报错:

org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, date tor [indices:data/write/bulk[s]] would be [31702096886/29.5],which is large than the limit of ......

这个报错就说明es出现了内存熔断的现象,es集群为了防止出现OOM的问题,有内存熔断的机制,如果jvm的内存使用量超过95%,则会拒绝所有的读写请求。

在kibana中查看ES集群资源占用情况,cpu和load负载都不高,发现各节点的jvm的使用率在90%左右,属于异常现象,如下图所示:

3、ES集群jvm内存占用分析

既然是jvm占用高,那就得分析出jvm中哪部分数据占用的内存高,对ES内存模型中的常用的index buffer、queryCache、requestCache、fieldDataCache、segmentsCache做内存占用分析,可在kibana中执行如下命令获取内存占用情况:

GET /_cat/nodes?v&h=name,port,sm

GET /_cat/nodes?v=true&h=name,heap*,fielddata.memory_size,query_cache.memory_size,request_cache.memory_size

得出结果如下:

内存类型

占用量

index buffer

3g (默认最大是占用jvm的10%,按照最大来算)

queryCache

1.2g

requestCache

500mb

fieldDataCache

1.5g

segmentsCache

260mb

index buffer是写入时候的缓存,默认是jvm的10%,es集群配置的jvm是31g,按照最大占用3g来算,加在一起也不过6.5g,才占用了21%左右,也就是说有将近70%的jvm不知道被谁占用了,非常奇怪。

4、jvm的GC 占比分析

    继续对jvm的GC做深层次的分析,找出到底是谁在占用大量的jvm。

在es节点的服务器上执行命令: jstat -gc  8021 5000

   其中8021是es服务的进程号,5000是每隔5000毫秒打印一次,如下图所示:

发现GC的老年代使用量OU达到了惊人的28143964 KB,也就是26.8GB,且长期不释放,这就是明显出现了内存泄漏的问题。

5、jvm dump文件分析

既然定位到老年代里有对象占用内存长期没有释放,就要做进一步的分析到底是被哪些对象占用。

借助jmap命令来生成dump文件,分析内存中对象的信息。

在es节点服务器上执行命令: jmap -dump:format=b,file=es-dump.dump 8021

其中es-dump.dump 是生成的dump文件名,8021是es服务的进程号。

然后将es-dump.dump 文件从服务器下载到本地,用VisualVM软件载入dump文件。

然后点击类,再点击大小,按照占用大小倒序排序,如下图所示:

很明显可以看到 float[ ] 、int[ ]、byte[ ] 三个类型的数组加起来占到了jvm的83%

继续分析三种数组的引用关系,发现都是被包含HanLP的类引用,如下图所示:

  因为ES集群中使用了HanLP分词插件,到这里就基本破案了,可以确定这次es的内存泄漏是由HanLP插件导致,随着数据的增多,HanLP生成的相关数据加载到内存中越来越多并且不释放,当内存使用量达到95%以后,es发生内存熔断,所有读写请求均被拒绝,使es集群处于崩溃不可用状态。

将HanLP插件从es集群中移除,重启集群,es各节点的jvm的使用量稳定在较低的水平,集群读写速度也恢复到正常情况。

三、总结

 排查类似jvm内存占用高等有关内存泄漏的问题,均可以使用类似上述gc的分析方法,先查看gc的年轻代和老年代的占比情况,然后在对jvm的dump文件做对象占用分析,基本可以定位到问题所在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值