了解elasticsearch jvm堆的使用情况

Nul*_*oet 9 elasticsearch

伙计们,

我正在尝试减少我的弹性搜索部署(单节点集群)中的内存使用量.

我可以看到正在使用的3GB JVM堆空间.要优化我首先需要了解瓶颈.我对如何拆分JVM使用的理解有限.

字段数据看起来消耗1.5GB,并且过滤器缓存和查询缓存组合消耗小于0.5GB,最多可增加2GB.

有人可以帮我理解elasticsearch在1GB的剩余部分吃掉了吗?

漫威截图

Val*_*Val 16

我无法确切知道你的确切设置,但是为了知道你的堆中发生了什么,你可以使用jvisualvm工具(与jdk捆绑在一起)和marvel或bigdesk插件(我的偏好)和_catAPI来分析这是怎么回事.

正如您所注意到的那样,堆拥有三个主要缓存,即:

这里提供很好的思维导图(感谢IgorKupczyński),总结了缓存的作用.对于ES需要创建以便正常运行的所有其他对象实例,这或多或少约30%的堆(在您的情况下为1GB)(稍后会详细介绍).

以下是我如何继续我的本地环境.首先,我开始我的节点新鲜(有Xmx1g)并等待绿色状态.然后我开始jvisualvm并将其挂钩到我的弹性搜索过程.我从Sampler选项卡中获取了一个堆转储,因此我可以稍后将其与另一个转储进行比较.我的堆最初看起来像这样(到目前为止只分配了最大堆的1/3):

在此输入图像描述

我还检查过我的字段数据和过滤缓存是空的:

在此输入图像描述

为了确保,我也跑了/_cat/fielddata,你可以看到,自从节点刚启动以来,字段数据还没有使用堆.

$ curl 'localhost:9200/_cat/fielddata?bytes=b&v'
id                     host       ip            node    total 
TMVa3S2oTUWOElsBrgFhuw iMac.local 192.168.1.100 Tumbler     0 
Run Code Online (Sandbox Code Playgroud)

这是最初的情况.现在,我们需要加热一点,所以我开始使用后端和前端应用程序来对本地ES节点施加压力.

过了一会儿,我的堆看起来像这样,所以它的大小或多或少增加了300 MB(139MB - > 452MB,不多但我在一个小数据集上运行了这个实验)

在此输入图像描述

我的缓存也增长了几个兆字节:

在此输入图像描述

$ curl 'localhost:9200/_cat/fielddata?bytes=b&v'
id                     host       ip            node      total 
TMVa3S2oTUWOElsBrgFhuw iMac.local 192.168.1.100 Tumbler 9066424
Run Code Online (Sandbox Code Playgroud)

在这一点上,我采取了另一个堆转储来深入了解堆如何进化,我计算了对象的保留大小,并将其与我刚启动节点后的第一个转储进行了比较.比较看起来像这样:

在保留大小增加的对象中,他通常怀疑是地图,当然还有任何与缓存相关的实体.但我们也可以找到以下类:

  • NIOFSDirectory 用于读取文件系统上的Lucene段文件
  • char数组或字节数组形式的许多实例化字符串
  • Doc值相关的类
  • 位集
  • 等等

在此输入图像描述

正如您所看到的,堆托管了三个主要缓存,但它也是Elasticsearch进程所需的所有其他Java对象所在的位置,并且不一定与缓存相关.

因此,如果您想控制堆使用情况,您显然无法控制ES需要正常运行的内部对象,但您肯定可以影响缓存的大小.如果您按照第一个项目符号列表中的链接,您将准确了解可以调整的设置.

调整缓存也许不是唯一的选择,也许您需要重写一些查询以更加内存友好或更改您的映射中的分析器或某些字段类型等.在您的情况下很难说,没有更多信息,但这应该给你一些线索.

继续按照我在这里的方式启动jvisualvm,了解你的应用程序(搜索+索引)在攻击ES时你的堆是如何增长的,你应该快速获得对那里发生的事情的一些见解.