断路器错误

编辑

Elasticsearch 使用断路器来防止节点耗尽 JVM 堆内存。如果 Elasticsearch 估计某个操作会超出断路器的限制,它会停止该操作并返回错误。

默认情况下,父断路器会在 JVM 内存使用率达到 95% 时触发。为了防止错误,我们建议在内存使用率持续超过 85% 时采取措施来减少内存压力。

诊断断路器错误

编辑

错误消息

如果请求触发了断路器,Elasticsearch 会返回一个 HTTP 状态码为 429 的错误。

{
  'error': {
    'type': 'circuit_breaking_exception',
    'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
    'bytes_wanted': 123848638,
    'bytes_limit': 123273216,
    'durability': 'TRANSIENT'
  },
  'status': 429
}

Elasticsearch 还会将断路器错误写入elasticsearch.log。当自动化进程(例如分配)触发断路器时,这很有帮助。

Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [num/numGB], which is larger than the limit of [num/numGB], usages [request=0/0b, fielddata=num/numKB, in_flight_requests=num/numGB, accounting=num/numGB]

检查 JVM 内存使用率

如果您已启用 Stack Monitoring,则可以在 Kibana 中查看 JVM 内存使用率。在主菜单中,单击Stack Monitoring。在 Stack Monitoring 的Overview页面上,单击NodesJVM Heap 列列出了每个节点的当前内存使用率。

您还可以使用 cat nodes API 来获取每个节点的当前 heap.percent

resp = client.cat.nodes(
    v=True,
    h="name,node*,heap*",
)
print(resp)
response = client.cat.nodes(
  v: true,
  h: 'name,node*,heap*'
)
puts response
const response = await client.cat.nodes({
  v: "true",
  h: "name,node*,heap*",
});
console.log(response);
GET _cat/nodes?v=true&h=name,node*,heap*

要获取每个断路器的 JVM 内存使用率,请使用 节点统计 API

resp = client.nodes.stats(
    metric="breaker",
)
print(resp)
response = client.nodes.stats(
  metric: 'breaker'
)
puts response
const response = await client.nodes.stats({
  metric: "breaker",
});
console.log(response);
GET _nodes/stats/breaker

防止断路器错误

编辑

减少 JVM 内存压力

高 JVM 内存压力通常会导致断路器错误。请参阅高 JVM 内存压力

避免在 text 字段上使用 fielddata

对于高基数的 text 字段,fielddata 会占用大量 JVM 内存。为了避免这种情况,Elasticsearch 默认禁用 text 字段上的 fielddata。如果您已启用 fielddata 并触发了fielddata 断路器,请考虑禁用它并使用 keyword 字段代替。请参阅 fielddata 映射参数

清除 fielddata 缓存

如果您已触发 fielddata 断路器并且无法禁用 fielddata,请使用 清除缓存 API 来清除 fielddata 缓存。这可能会中断任何正在进行的、使用 fielddata 的搜索。

resp = client.indices.clear_cache(
    fielddata=True,
)
print(resp)
response = client.indices.clear_cache(
  fielddata: true
)
puts response
const response = await client.indices.clearCache({
  fielddata: "true",
});
console.log(response);
POST _cache/clear?fielddata=true