如何排查 Amazon Elasticsearch Service 集群上的高 JVM 内存压力问题?

上次更新时间:2020 年 4 月 14 日

我的 Amazon Elasticsearch Service (Amazon ES) 集群的 JVM 内存压力高。 不同的 JVM 内存压力水平分别意味着什么,如何降低该压力水平?

解决方法

JVM 内存压力指的是 Java 在集群节点中占用的堆百分比。以下指南用来指示 JVM 内存压力百分比的意义:

  • 如果 JVM 内存压力达到 75%,则 Amazon ES 会触发并发标记扫描 (CMS) 垃圾收集器。垃圾收集是 CPU 密集型过程。如果 JVM 内存压力在此百分比下保持几分钟,您可能会遇到 ClusterBlockException、JVM OutOfMemoryError 或其他集群性能问题。
  • 如果 JVM 内存压力持续 30 分钟超过 92%,则 Amazon ES 会阻止所有的写入操作。
  • 如果 JVM 内存压力达到 100%,则 Amazon ES JVM 会被配置为退出且最终在 OutOfMemory (OOM) 上重新启动。

高 JVM 内存压力可能因以下原因造成:

  • 至集群的请求数量激增。
  • 聚合、通配符以及在查询中选择了较宽的时间范围。
  • 各节点间的分区分配不平衡或者一个集群中的分区太多。
  • 字段数据或索引映射激增。
  • 无法处理传入负载的实例类型。

您可以通过减少至集群的流量来解决高 JVM 内存压力问题。要减少至集群的流量,请遵照以下最佳实践:

  • 使用 POST /index_name/_cache/clear?fielddata=true API 操作清除字段数据缓存。
    注意:清除缓存可能会中断正在进行的查询。
  • 避免聚合文本字段或将映射类型更改为关键字。
  • 扩展域(以使每个节点的最大堆大小为 32GB)。
  • 启用慢速日志以找出错误的请求。
    注意:验证 JVM 内存压力是否低于 90%。有关慢速 Elasticsearch 查询的更多信息,请参阅 Elastic 网站上的高级调整:找到并修复慢速 Elasticsearch 查询
  • 优化搜索索引,然后选择正确的分区数。有关索引和分区计数的更多信息,请参阅开始使用 Amazon Elasticsearch Service:我需要多少个分区?
  • 通过删除旧索引或未使用的索引减少分区数。
  • 设置 JVM 的内存断路器。有关 JVM 断路器的更多信息,请参阅 JVM OutOfMemoryError

有关如何排查 JVM 内存压力高的问题的更多信息,请参阅我的 Elasticsearch 节点为什么崩溃了?