我无法告诉你确切的设置,但为了知道你的堆中发生了什么,你可以将 jvisualvm 工具(与 jdk 捆绑在一起)与 marvel 或大桌面插件 http://bigdesk.org/(我的偏好)和_cat APIs https://www.elastic.co/guide/en/elasticsearch/reference/current/cat.html来分析发生了什么。
正如您所注意到的,堆托管三个主要缓存,即:
- the 字段数据缓存 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-fielddata.html:默认情况下无界,但可以通过以下方式控制
indices.fielddata.cache.size
(在你的例子中,它似乎占堆的 50% 左右,可能是由于现场数据断路器 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/circuit-breaker.html#fielddata-circuit-breaker)
- the 节点查询/过滤缓存 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/query-cache.html:堆的 10%
- the 分片请求缓存 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/shard-request-cache.html:堆的 1%,但默认禁用
有很好的思维导图可用here http://igor.kupczynski.info/2015/04/06/fielddata.html(感谢 Igor Kupczyński)总结了缓存的作用。这就留下了大约 30% 的堆(在你的例子中为 1GB)用于 ES 需要创建的所有其他对象实例,以便正常运行(稍后会详细介绍)。
这是我在本地环境中进行的操作。首先,我重新启动了我的节点(使用Xmx1g
)并等待绿色状态。然后我启动了 jvisualvm 并将其挂接到我的 elasticsearch 进程上。我从“采样器”选项卡中获取了堆转储,以便稍后可以将其与另一个转储进行比较。我的堆最初看起来像这样(到目前为止仅分配了最大堆的 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
此时,我进行了另一个堆转储以深入了解堆的演变过程,我计算了保留尺寸 https://stackoverflow.com/questions/12600744/what-does-retained-size-mean-in-jvisualvms-memory-inspector的对象,我将其与启动节点后拍摄的第一个转储进行了比较。比较如下:
在保留大小增加的对象中,他通常怀疑当然是地图以及任何与缓存相关的实体。但我们还可以找到以下类:
-
NIOFSDirectory https://lucene.apache.org/core/5_3_0/core/org/apache/lucene/store/NIOFSDirectory.html用于读取文件系统上的 Lucene 段文件
- 许多字符数组或字节数组形式的内部字符串
- 文档值相关类
- Bit sets
- etc
正如您所看到的,堆托管三个主要缓存,但它也是 Elasticsearch 进程需要的所有其他 Java 对象的驻留位置,这些对象不一定与缓存相关。
因此,如果您想控制堆的使用,显然您无法控制 ES 正常运行所需的内部对象,但您绝对可以影响缓存的大小。如果您点击第一个项目符号列表中的链接,您将准确了解可以调整哪些设置。
此外,调整缓存可能不是唯一的选择,也许您需要重写一些查询以更加内存友好,或者更改分析器或映射中的某些字段类型等。在没有更多信息的情况下,很难判断您的情况,但这应该会给你一些线索。
继续以与我在这里相同的方式启动 jvisualvm 并了解当您的应用程序(搜索+索引)访问 ES 时您的堆如何增长,您应该快速了解其中发生的情况。