Elasticsearch 高 RSS 内存消耗

Elasticsearch 高 RSS 内存消耗

我发现我的 elasticsearch 实例中的内存消耗太高。

我设置了 ES_HEAP_SIZE=4g。

ES 的启动命令以以下内容开头: /usr/lib/jvm/java-8-oracle/jre/bin/java -Xms4g -Xmx4g

到目前为止,一切都很好。

但我看到 RSS 内存消耗超过 7GB。

这是 /proc/status 输出:http://pastebin.com/mXW6Vnfc

但当我运行时jstat -gc一切看起来都很正常,我看到 OC 大约有 3.7GB,EC 大约有 270 MB(http://pastebin.com/c84urvSM)。

这是已排序的 pmap 输出:http://pastebin.com/GG92Ercr

你知道为什么内存消耗这么高吗?

此外,ES 在 OpenVZ 下的虚拟服务器上运行。

答案1

问题可能出在 JVM 中,如果你启动了 ES 的多个实例,请使用 Java Mission Control 进行调查http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-1998576.html或 jconsolehttps://docs.oracle.com/javase/8/docs/technotes/guides/management/jconsole.html。这将让您了解为什么它会消耗这么多内存。

请记住,JVM 使用堆内存之外的 GC 和其他进程。使用 -xms 1024 启动 ES,然后让它增长。另外据我记得,java 将 -xms、-xmx 参数视为 MB 而不是 GB,为了安全起见,将所有内容转换为 MB。

答案2

用于jvisualvm查看堆消耗(还有更多),它是 java 的官方调试和分析工具,默认与 java 一起安装。

将其附加到 elasticsearch 进程,检查 -Xmx 和 -Xms 标志是否具有正确的值并查看图表。这非常简单。

由于您设置了最小和最大堆,因此 Java 进程应始终具有 4 GB 的堆。它应在系统上消耗 4-4.5 GB,因为管理不计入堆一部分的堆会产生一些开销。

无论如何,java 不允许进程使用比配置更多的堆(如果进程试图这样做,它会终止进程)。很可能有其他程序正在使用您计算机上的内存。使用tophtop查看其他正在运行的进程。

答案3

您使用 ES_HEAP_SIZE 设置的是 JVM 上运行的程序可用的 Java 堆大小。除此之外,JVM 有自己的开销,还有来自 GC 的开销(其数据不计入 Java 堆),并且每个正在运行的线程都需要内存来存储其堆栈(您有多少个线程以及堆栈大小是多少?)。ElasticSearch 本身可能不使用堆外存储,但这始终是需要注意的事情。

我听说过一些案例,更改内存分配器有助于减少 JVM 的总占用空间(jemalloc 与 glibc malloc)。最后,如果可能的话,我会尝试不同的(更新的?)JVM 版本或不同的 GC 算法...

相关内容