高 JVM 内存压力
编辑高 JVM 内存压力编辑
高 JVM 内存使用率会导致集群性能下降并触发 断路器错误。为了防止这种情况,我们建议在节点的 JVM 内存使用率持续超过 85% 时采取措施降低内存压力。
诊断高 JVM 内存压力编辑
检查 JVM 内存压力
从您的部署菜单中,点击 Elasticsearch。在 实例 下,每个实例都会显示一个 JVM 内存压力 指示器。当 JVM 内存压力达到 75% 时,指示器会变为红色。
您也可以使用 节点统计 API 来计算每个节点的当前 JVM 内存压力。
response = client.nodes.stats( filter_path: 'nodes.*.jvm.mem.pools.old' ) puts response
GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
使用响应来计算内存压力,如下所示
JVM 内存压力 = used_in_bytes
/ max_in_bytes
要计算每个节点的当前 JVM 内存压力,请使用 节点统计 API。
response = client.nodes.stats( filter_path: 'nodes.*.jvm.mem.pools.old' ) puts response
GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
使用响应来计算内存压力,如下所示
JVM 内存压力 = used_in_bytes
/ max_in_bytes
检查垃圾回收日志
随着内存使用量的增加,垃圾回收会变得更加频繁,并且需要更长的时间。您可以在 elasticsearch.log
中跟踪垃圾回收事件的频率和持续时间。例如,以下事件表明 Elasticsearch 在过去 40 秒中花费了超过 50%(21 秒)的时间进行垃圾回收。
[timestamp_short_interval_from_last][INFO ][o.e.m.j.JvmGcMonitorService] [node_id] [gc][number] overhead, spent [21s] collecting in the last [40s]
捕获 JVM 堆转储
为了确定高 JVM 内存压力的确切原因,请在 JVM 内存使用率较高时捕获其堆转储。
降低 JVM 内存压力编辑
本节包含一些降低 JVM 内存压力的常见建议。
减少分片数量
每个分片都会使用内存。在大多数情况下,少量大型分片比许多小型分片使用更少的资源。有关减少分片数量的提示,请参阅 调整分片大小。
昂贵的搜索可能会使用大量的内存。为了更好地跟踪集群上的昂贵搜索,请启用 慢日志。
昂贵的搜索可能具有较大的 size
参数,使用具有大量桶的聚合,或包含 昂贵的查询。为了防止昂贵的搜索,请考虑以下设置更改
- 使用
index.max_result_window
索引设置降低size
限制。 - 使用 search.max_buckets 集群设置减少允许的聚合桶的最大数量。
- 使用
search.allow_expensive_queries
集群设置禁用昂贵的查询。
response = client.indices.put_settings( body: { 'index.max_result_window' => 5000 } ) puts response response = client.cluster.put_settings( body: { persistent: { 'search.max_buckets' => 20_000, 'search.allow_expensive_queries' => false } } ) puts response
PUT _settings { "index.max_result_window": 5000 } PUT _cluster/settings { "persistent": { "search.max_buckets": 20000, "search.allow_expensive_queries": false } }
防止映射爆炸
定义太多字段或将字段嵌套得太深会导致 映射爆炸,从而使用大量的内存。为了防止映射爆炸,请使用 映射限制设置 来限制字段映射的数量。
分散批量请求
虽然比单个请求更高效,但大型 批量索引 或 多搜索 请求仍然会导致高 JVM 内存压力。如果可能,请提交较小的请求,并在它们之间留出更多时间。
升级节点内存
繁重的索引和搜索负载会导致高 JVM 内存压力。为了更好地处理繁重的负载,请升级您的节点以增加其内存容量。