ElasticSearch低版本由于嵌套查询导致的OOME问题排查 (BitSet导致)
环境和现象:
主机是65G内存,es配置为32G;es版本是1.7.2。
操作系统是centos6.8。es集群总共有5个节点,运维说其中一个节点总是报内存溢出
分析
运维给了个几十G的 .hprof
文件,没啥好说的,直接用MAT来分析这个dump文件
我们直接加载然后看下饼图和详细占用。
下面是MAT的分析情况:
可以直观的看到占用内存最多的就是这个 FixedBitSetFilterCache。
BitsetFilterCache
是Filter缓存, 属于Index级别。
结论
其实排查的话经过上面的分析就差不多了, 因为得知了具体是什么东西占用多, 所以只需要去查这个对象在什么情况下会被创建就可以了。
根据我Google和StackOverflow的成果, 还是得到了不少有用的信息的 (看下面)。
最终结论是因为ES的嵌套查询/排序导致创建了大量的BitSet, 从而OOM, 在低版本是有这个问题 ,高版本才优化了一下, 1.7.2确实是有点太低了,也不知道是什么年代部署的了。。。
下面是得出此结论相关的资料。
以下是来自于ES的github issue (https://github.com/elastic/elasticsearch/issues/14903) 的说明:
FixedBitSetFilterCache is a data structure that is loaded eagerly in memory (by default) to support nested query/filter and nested aggregations. However, the problem is that it can cause it to use too much heap for it is loaded for all nested fields (regardless of whether these fields are being used). To prevent this from happening, a common configuration workaround is to set index.load_fixed_bitset_filters_eagerly: false in the yml of the nodes and restart them to prevent the nodes from running OOM when attempting to eagerly load the fixedbitsets.
和此问题相似的ISSUE:
https://github.com/elastic/elasticsearch/issues/8394
https://github.com/elastic/elasticsearch/issues/10224
《深入理解Elasticsearch(原书第2版)》一2.4 过滤器的使用及作用原理
摘抄片段:
通常,过滤器都是很快的。这一点有多种原因。首先,最重要的一点是,由过滤器所处理的查询部分不需要计算文档得分。之前我们就提到过,打分过程与给定查询和索引中的文档集合密切相关。
嵌套排序的bitset优化在2.0版本的PR:
https://github.com/elastic/elasticsearch/pull/9199
解决方案:
修改elasticseatch.yml
后面叫运维先改了一台机子重启试试, 果然那一台之后就没报错了,反而是另一台没配置的开始了OOM。
随后将全部的机子都修改重启。
29.9G的快照,32G内存的电脑可以打开么