民间,
我正在尝试减少弹性搜索部署(单节点群集)中的内存使用量。
我可以看到正在使用的3GB JVM堆空间。 要优化我首先需要了解瓶颈。 我对如何拆分JVM使用情况的理解有限。
现场数据看起来消耗1.5GB并过滤缓存&查询缓存组合消耗小于0.5GB,最多可增加2GB
有人可以帮我理解elasticsearch在1GB的剩余部分吃掉了吗?
答案 0 :(得分:14)
我无法确切知道您的确切设置,但为了了解您的堆中发生了什么,您可以使用jvisualvm工具(与jdk捆绑在一起)以及奇迹或bigdesk plugin(我的偏好) )和_cat
APIs来分析正在发生的事情。
正如您所正确注意到的,堆有三个主要缓存,即:
indices.fielddata.cache.size
控制(在您的情况下,它似乎是堆的大约50%,可能是由于fielddata circuit breaker)< / LI>
有一个很好的思维导图here(感谢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
这是最初的情况。现在,我们需要加热这一点,所以我启动了我的后端和前端应用程序,以对本地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
此时我采用了另一个堆转储来深入了解堆的进展情况,我计算了对象的retained size,并将它与我刚启动节点后的第一个转储进行了比较。比较看起来像这样:
在保留大小增加的对象中,他通常怀疑是地图,当然还有任何与缓存相关的实体。但我们也可以找到以下类:
NIOFSDirectory
用于读取文件系统上的Lucene段文件正如您所看到的,堆托管了三个主要缓存,但它也是Elasticsearch进程所需的所有其他Java对象所在的位置,并且不一定与缓存相关。
因此,如果您想控制堆使用情况,您显然无法控制ES需要正常运行的内部对象,但您肯定会影响缓存的大小调整。如果您按照第一个项目符号列表中的链接,您将准确了解可以调整的设置。
同样调整缓存可能不是唯一的选择,也许您需要重写一些查询以更加内存友好,或者更改您的分析器或映射中的某些字段类型等。在您的情况下很难说,没有更多信息,但这应该给你一些线索。
继续按照我在这里的方式启动jvisualvm,了解你的应用程序(搜索+索引)在攻击ES时你的堆是如何增长的,你应该快速获得对那里正在发生的事情的一些见解。
答案 1 :(得分:1)
Marvel只绘制堆上的一些实例,在这种情况下需要像Caches一样进行监视。
缓存仅代表总堆使用量的一部分。还有很多其他实例会占用堆内存,而这些实例可能没有直接绘制这个奇迹界面。
因此,并非所有在ES中占用的堆都只能通过缓存。
为了清楚地了解不同实例的堆的确切用法,您应该对该进程进行堆转储,然后使用Memory Analyzer工具对其进行分析,该工具可以为您提供准确的图片。