记一次Elasticsearch OOM的优化过程——基于segments force merge 和 store type 转为 niofs
首选,说明笔者的机器环境(不结合环境谈解决方案都是耍流氓): cpu 32核,内存128g,非固态硬盘: raid0 (4t * 6),单节点,数据量在700g到1800g,索引15亿~21亿。大人,在蘑菇街,可多集群分片,固态硬盘,比不起啊。
转载请注明出处:https://www.cnblogs.com/naughtycat/p/elasticsearch-oom-optimize-story.html
业务场景:
保存7天索引,每天有400g。发现es时不时的oom,和重启。当索引超过500g的时候,es重启到加载所有分片,时间约30分钟到1小时。
题外话,es oom 会生成 .hprof 文件,如下图(作者【coderbaby】):
用jhat来分析oom堆转储文件,具体命令如: jhat -port 7401 -j-xmx4g java_pid19546.hprof
解决办法:
- 改文件存储类型,减少内存占用
设置存储类型为:“nifos” ,即: "index.store.type": "niofs" (原来为“mmapfs”,详见附2)。mmapfs — index映射到内存,niofs — 并发多线程以nio的方式读取index文件。
效果:在600g左右的索引,5天索引,确实没有了oom。但一旦增大到7个索引,就不行了。用jstat命令,即:stat -gcutil 6811 (es的pid)查看es的jvm,如下图:
o: old space utilization as a percentage of the space's current capacity (老年代空间占用率)。o最高达到79,就往下降,原来为存储类型为“mmapfs”,o很容易就飙到100.
- 关闭暂时不用的索引,减少打开索引的数量
关闭索引(文件仍然存在于磁盘,只是释放掉内存,需要的时候可重新打开)。设置打开索引参数: "__es.maxpermanentlyopenindices":4 (最大打开索引:7改为4)。
- 扩大堆内存
设置堆大小,从15g提高到30g,即: -xms30g -xmx30g (注意:最大不要超过物理内存的 %50)
- 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多万,具体如下表:
index | total_segments_berfore_merge | total_segments_after_merge | query_ip_after(seconds) | query_ip_after(seconds) | decrease(count/percentage) |
pcap_flow-2019-12-09 | 1412695374 | 137249867 | 10 | 3.6 | 40196703/ %2.845 |
可通过命令查看各个分片的情况,如下(可查看总的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完成为止
4)restful api 查看_segments,如下:
curl -x get "localhost:9200/_cat/segments?v&pretty"
效果如下图:
题外话,如果贵司银子多,可以集群分片,搞ssd,否则只有结构优化,这一招。
附:
1)官网 index force merge说明:
2) es 存储类型:
3)merge 线程数:
4)磁盘阵列raid: https://zh.wikipedia.org/wiki/raid
5)关于索引合并的统计分析:
*****************************************************************************************************
精力有限,想法太多,专注做好一件事就行
- 我只是一个程序猿。5年内把代码写好,技术博客字字推敲,坚持零拷贝和原创
- 写博客的意义在于打磨文笔,训练逻辑条理性,加深对知识的系统性理解;如果恰好又对别人有点帮助,那真是一件令人开心的事
*****************************************************************************************************
下一篇: oracle逻辑存储结构