高 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

检查垃圾回收日志

随着内存使用量的增加,垃圾回收会变得更加频繁,并且需要更长的时间。您可以在 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 参数,使用具有大量桶的聚合,或包含 昂贵的查询。为了防止昂贵的搜索,请考虑以下设置更改

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 内存压力。为了更好地处理繁重的负载,请升级您的节点以增加其内存容量。