了解elasticsearch jvm堆的使用情况

时间:2016-03-02 08:19:49

标签: elasticsearch

民间,

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

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

现场数据看起来消耗1.5GB并过滤缓存&查询缓存组合消耗小于0.5GB,最多可增加2GB

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

Marvel screenshot

2 个答案:

答案 0 :(得分:14)

我无法确切知道您的确切设置,但为了了解您的堆中发生了什么,您可以使用jvisualvm工具(与jdk捆绑在一起)以及奇迹或bigdesk plugin(我的偏好) )和_cat APIs来分析正在发生的事情。

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

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

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

enter image description here

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

enter image description here

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

$ curl 'localhost:9200/_cat/fielddata?bytes=b&v'
id                     host       ip            node    total 
TMVa3S2oTUWOElsBrgFhuw iMac.local 192.168.1.100 Tumbler     0 

这是最初的情况。现在,我们需要加热这一点,所以我启动了我的后端和前端应用程序,以对本地ES节点施加一些压力。

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

enter image description here

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

enter image description here

$ curl 'localhost:9200/_cat/fielddata?bytes=b&v'
id                     host       ip            node      total 
TMVa3S2oTUWOElsBrgFhuw iMac.local 192.168.1.100 Tumbler 9066424

此时我采用了另一个堆转储来深入了解堆的进展情况,我计算了对象的retained size,并将它与我刚启动节点后的第一个转储进行了比较。比较看起来像这样:

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

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

enter image description here

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

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

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

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

答案 1 :(得分:1)

Marvel只绘制堆上的一些实例,在这种情况下需要像Caches一样进行监视。

缓存仅代表总堆使用量的一部分。还有很多其他实例会占用堆内存,而这些实例可能没有直接绘制这个奇迹界面。

因此,并非所有在ES中占用的堆都只能通过缓存。

为了清楚地了解不同实例的堆的确切用法,您应该对该进程进行堆转储,然后使用Memory Analyzer工具对其进行分析,该工具可以为您提供准确的图片。