高 JVM 内存压力

编辑

高 JVM 内存使用率可能会降低集群性能并触发断路器错误。为了防止这种情况,我们建议如果节点的 JVM 内存使用率持续超过 85%,则采取措施降低内存压力。

诊断高 JVM 内存压力

编辑

检查 JVM 内存压力

从您的部署菜单中,点击Elasticsearch。在实例下,每个实例都会显示一个JVM 内存压力指示器。当 JVM 内存压力达到 75% 时,指示器会变为红色。

您还可以使用节点统计 API计算每个节点当前的 JVM 内存压力。

resp = client.nodes.stats(
    filter_path="nodes.*.jvm.mem.pools.old",
)
print(resp)
response = client.nodes.stats(
  filter_path: 'nodes.*.jvm.mem.pools.old'
)
puts response
const response = await client.nodes.stats({
  filter_path: "nodes.*.jvm.mem.pools.old",
});
console.log(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 参数,使用具有大量桶的聚合,或包含代价高昂的查询。为了防止代价高昂的搜索,请考虑以下设置更改

resp = client.indices.put_settings(
    settings={
        "index.max_result_window": 5000
    },
)
print(resp)

resp1 = client.cluster.put_settings(
    persistent={
        "search.max_buckets": 20000,
        "search.allow_expensive_queries": False
    },
)
print(resp1)
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
const response = await client.indices.putSettings({
  settings: {
    "index.max_result_window": 5000,
  },
});
console.log(response);

const response1 = await client.cluster.putSettings({
  persistent: {
    "search.max_buckets": 20000,
    "search.allow_expensive_queries": false,
  },
});
console.log(response1);
PUT _settings
{
  "index.max_result_window": 5000
}

PUT _cluster/settings
{
  "persistent": {
    "search.max_buckets": 20000,
    "search.allow_expensive_queries": false
  }
}

防止映射爆炸

定义过多的字段或嵌套字段过深会导致映射爆炸,从而使用大量的内存。为了防止映射爆炸,请使用映射限制设置来限制字段映射的数量。

分散批量请求

虽然比单个请求更有效,但大型批量索引多搜索请求仍然可能产生高 JVM 内存压力。如果可能,提交较小的请求并在它们之间留出更多时间。

升级节点内存

繁重的索引和搜索负载会导致高 JVM 内存压力。为了更好地处理繁重的负载,请升级您的节点以增加其内存容量。