高 JVM 内存压力
编辑高 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
要计算每个节点当前的 JVM 内存压力,请使用节点统计 API。
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
参数,使用具有大量桶的聚合,或包含代价高昂的查询。为了防止代价高昂的搜索,请考虑以下设置更改
- 使用
index.max_result_window
索引设置降低size
限制。 - 使用search.max_buckets集群设置减少允许的最大聚合桶数。
- 使用
search.allow_expensive_queries
集群设置禁用代价高昂的查询。 - 使用
search.default_search_timeout
集群设置设置默认搜索超时。
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 内存压力。为了更好地处理繁重的负载,请升级您的节点以增加其内存容量。