Elasticsearch 堆内存使用情况和 JVM 垃圾回收
作者:来自 Elastic Kofi Bartlett
探索 Elasticsearch 堆内存使用情况和 JVM 垃圾回收,包括最佳实践以及在堆内存使用过高或 JVM 性能不佳时的解决方法。
堆内存大小是分配给 Elasticsearch 节点中 Java 虚拟机的 RAM 数量。
从 7.11 版本开始,Elasticsearch 默认会根据节点的角色和总内存自动设置 JVM 堆内存大小。对于大多数生产环境,推荐使用默认配置。然而,如果你希望手动设置 JVM 堆内存大小,一般规则是将 -Xms 和 -Xmx 设置为相同的值,该值应为系统总可用内存的 50%,但最大不应超过大约 31GB。
较大的堆内存可以为节点提供更多用于索引和搜索操作的内存。但节点也需要内存用于缓存,因此使用 50% 可以在两者之间保持健康的平衡。出于同样的原因,在生产环境中应该避免在与 Elasticsearch 相同的节点上运行其他高内存占用的进程。
通常,堆使用率会呈锯齿状波动,在最大堆使用量的 30% 到 70% 之间。这是因为 JVM 会逐渐增加堆使用率,直到垃圾回收过程释放出内存。当垃圾回收过程无法跟上时,就会出现高堆使用率。一个高堆使用率的迹象是垃圾回收无法将堆使用率降低到大约 30%。
在上面的图像中,你可以看到 JVM 堆的正常锯齿状变化。
你还会看到有两种类型的垃圾回收:年轻代(young) GC 和老年代(old) GC。
在健康的 JVM 中,垃圾回收理想情况下应满足以下条件:
- 年轻代 GC 处理速度快(在 50 毫秒内完成)。
- 年轻代 GC 执行频率不高(大约每 10 秒一次)。
- 老年代 GC 处理速度快(在 1 秒内完成)。
- 老年代 GC 执行频率不高(每 10 分钟或更久一次)。
当堆内存使用过高或 JVM 性能不佳时的解决方法
堆内存使用增加可能由多种原因引起:
分片过多( Oversharding )
请在这里参阅关于分片过多的文档。
聚合数据量过大( Large aggregation sizes )
为了避免聚合数据量过大,请在查询中尽量减少聚合桶( size )的数量。
GET /_search
{"aggs" : {"products" : {"terms" : {"field" : "product","size" : 5}}}
}
你可以使用慢查询日志( slow logs ),并通过以下方式在特定索引上启用它:
PUT /my_index/_settings
{"index.search.slowlog.threshold.query.warn": "10s","index.search.slowlog.threshold.query.info": "5s","index.search.slowlog.threshold.query.debug": "2s","index.search.slowlog.threshold.query.trace": "500ms","index.search.slowlog.threshold.fetch.warn": "1s","index.search.slowlog.threshold.fetch.info": "800ms","index.search.slowlog.threshold.fetch.debug": "500ms","index.search.slowlog.threshold.fetch.trace": "200ms","index.search.slowlog.level": "info"
}
执行时间长的查询很可能是资源密集型的操作。
批量索引请求过大( Excessive bulk index size )
如果你发送的是大型请求,这可能导致堆内存消耗过高。尝试减小批量索引请求的大小。
映射问题( Mapping issues )
特别是当你使用了 fielddata: true
时,这可能会大量占用 JVM 堆内存。
堆内存大小设置不当( Heap size incorrectly set )
你可以通过设置环境变量手动定义堆内存大小:
ES_JAVA_OPTS="-Xms2g -Xmx2g"
在你的 Elasticsearch 配置目录中编辑 jvm.options
文件:
-Xms2g
-Xmx2g
环境变量设置优先于文件设置。
需要重启节点才能使设置生效。
JVM 新代比例设置不当( JVM new ratio incorrectly set )
通常不需要手动设置这个值,因为 Elasticsearch 默认会设置此值。这个参数定义了 JVM 中 “新生代” 和 “老年代” 对象可用空间的比例。
如果你发现老年代 GC 变得非常频繁,可以尝试在 Elasticsearch 配置目录中的 jvm.options
文件中专门设置这个值。
-XX:NewRatio=3
在大型 Elasticsearch 集群中管理堆内存使用和 JVM 垃圾回收的最佳实践是什么?
在大型 Elasticsearch 集群中管理堆内存使用和 JVM 垃圾回收的最佳实践是确保堆内存大小设置为可用内存的 50% 的最大值,并根据特定用例优化 JVM 垃圾回收设置。监控堆内存大小和垃圾回收指标以确保集群运行在最佳状态是非常重要的。具体来说,重要的是监控 JVM 堆内存大小、垃圾回收时间和垃圾回收暂停时间。此外,还需要监控垃圾回收周期的数量以及在垃圾回收中花费的时间。通过监控这些指标,可以识别堆内存或垃圾回收设置的潜在问题,并在必要时采取纠正措施。
想要获得 Elastic 认证吗?了解下一期 Elasticsearch 工程师培训的时间!
Elasticsearch 包含了许多新功能,帮助你为特定用例构建最佳的搜索解决方案。深入我们的示例笔记本,了解更多内容,开始免费云试用,或者立即在本地机器上尝试 Elastic。
原文:Elasticsearch heap size usage and JVM garbage collection - Elasticsearch Labs