Elasticsearch OOM(内存溢出)

首先,说明笔者的机器环境(不结合环境谈解决方案都是耍流氓): cpu 32核,内存128G,非固态硬盘:RAID0 (4T * 6),单节点,数据量在700G到1800G,索引15亿~21亿。敖丙大人,在蘑菇街,可多集群分片,固态硬盘,比不起啊。

业务场景

保存7天索引,每天有400G~500G。发现ES时不时的OOM(out of memory)和重启。当索引超过500G的时候,ES重启到加载所有分片,时间约30分钟到1小时。

题外话,ES OOM 会生成 .hprof 文件,如下图:
在这里插入图片描述
用jhat来分析OOM堆转储文件,具体命令:

 jhat -port 7401 -J-Xmx4G java_pid19546.hprof

解决办法

1、改文件存储类型,减少内存占用

设置存储类型为:“hybridfs” ,即:“index.store.type”: “hybridfs” (原来为“mmapfs”,详见附2;另外,ES 5.6应为“fs”,不支持“hybridfs”,最新的7.4版本支持“hybridfs”)。

  • mmapfs:index映射到内存;
  • niofs :并发多线程以NIO的方式读取index文件;
  • hybridfs:混合 mmafs和niofs ,根据读取模式选择最佳的文件系统。

效果:在600G左右的索引,5天索引,确实没有了OOM。但一旦增大到7个索引,就不行了。用jstat命令,即:

jstat -gcutil 6811 (ES的PID)

查看ES的jvm,如下图:
在这里插入图片描述
O: Old space utilization as a percentage of the space’s current capacity (老年代空间占用率)。O最高达到79,就往下降,原来为存储类型为“mmapfs”,O很容易就飙到100。

2、不要自己创建文档ID

ES默认会自动创建文档Id"(如:_id": “AW8922mK8RqpiZJD9zb2”),如果自己生成Id,则每次存储新的文档的时候,ES都会查看整个分片是否已经存在该Id。如果分片存储有上千万的文档,这是一个比较耗时的操作。

3、关闭暂时不用的索引,减少打开索引的数量

关闭索引(文件仍然存在于磁盘,只是释放掉内存,需要的时候可重新打开)。设置打开索引参数:"__es.maxPermanentlyOpenIndices":4 (最大打开索引:7改为4)。

4、扩大堆内存

设置堆大小,从15G提高到30G,即: -Xms30g -Xmx30g (注意:最大不要超过物理内存的 %50)。

5、扩大虚拟内存空间

命令:

sysctl -w vm.max_map_count=2621440(默认值是 “262144”)
扩大这个,可以防止这个数量太低而导致的OOM(详见附6)

6、forcemerge

设置merge时最大的线程数:index.merge.scheduler.max_thread_count。固态硬盘——默认最大值 Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)) ,普通旋转磁盘——设置为1。

笔者机器上,单merge 线程,300G的索引耗时:7个小时

优化效果:term 单条件查询,查询时间从10秒多提高到3秒多,索引减少约%2.85,减少4000多万,具体如下表:
在这里插入图片描述
可通过命令查看各个分片的情况,如下(可查看总的segments数量):

curl -s "http://localhost:9200/_cat/segments/pcap_flow-2019-12-10?v&h=shard,segment,size,size.memory" | awk '{sum += $NF} END {print sum}'

force merge的restful API:

curl -X POST "localhost:9200/pcap_flow-2019-12-11/_forcemerge?max_num_segments=2"

说明:

1)max_num_segments, 设置最大segement数量,数量越小,查询速度提高越明显,但merge耗时越长;

2)全部merge,不加索引ID,则如下:

curl -X POST “localhost:9200/_forcemerge”
3)merge过程是串行的,如果同时merge多个,后面的会被阻塞,直到第一个merge完成为止。另外,对于不再有写入的更新的index,才建议force merge,不然反而会让搜索的性能更差;

4)restful api 查看_segments,如下:

curl -X GET “localhost:9200/_cat/segments?v&pretty”
效果如下图:
在这里插入图片描述
题外话,如果贵司银子多,可以集群分片,搞SSD,否则只有结构优化,这一招。

参考连接 :

遇到Elasticsearch OOM(内存溢出),除了瞪白眼,还能干啥…
https://www.jianshu.com/p/8b96865efd0e

您好!对于ElasticsearchOOM(Out of Memory)问题,有几个可能的原因和解决方案。 1. 配置调整:检查Elasticsearch的JVM堆内存设置。默认情况下,Elasticsearch将堆内存设置为1GB,但在处理大量数据时可能会导致OOM。您可以通过编辑elasticsearch.yml文件中的"Xms"和"Xmx"参数来增加堆内存大小。例如,设置为"-Xms4g -Xmx4g"将堆内存设置为4GB。请确保服务器具有足够的物理内存来支持您设置的堆内存大小。 2. 索引优化:检查索引的设置和映射。索引的映射定义了字段类型和分析器等信息,如果不正确地配置索引,可能会导致内存占用过高。尽量使用合适的字段类型,并避免在索引中存储大量的不必要字段。 3. 查询调优:检查查询的复杂性和性能。复杂的查询可能会消耗大量的内存资源,特别是在处理大量数据时。优化查询可以包括使用更简单的查询语句、减少返回结果的数量或使用聚合操作等。 4. 分片设置:检查索引的分片设置。每个分片都需要一定数量的内存来处理数据。如果您的集群中有过多的分片,可能会导致内存不足。您可以减少分片的数量或增加服务器的内存来解决此问题。 5. 版本更新:如果您正在使用旧版本的Elasticsearch,考虑升级到最新版本。每个版本都会进行性能和稳定性的改进,可能会提供更好的内存管理和OOM问题的修复。 请注意,OOM问题可能有多个原因,并且解决方案可能因您的具体环境和使用情况而有所不同。建议您在修改配置之前备份数据和配置文件,并在生产环境中进行测试和验证。如果问题仍然存在,您可以检查Elasticsearch的日志文件以获取更多详细信息,或者参考Elasticsearch社区论坛等资源寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值