ES异常排查之-熔断

2022-05-25 20:52:59 浏览数 (1)

集群熔断-Data too large

问题现象:

排查监控发现存在熔断,查看日志如下

代码语言:go复制
应用日志:
2022-05-24T21:17:53.142 0800    ERROR   service/task.go:580     SearchSesionlogRecord err=%v    
{"error": "elastic: Error 429 (Too Many Requests): 
[parent] Data too large, data for [<http_request>] would be [15578885702/14.5gb], 
which is larger than the limit of [15461882265/14.3gb], 
real usage: [15578885480/14.4gb], new bytes reserved: [222/222b], 
usages [request=173877960/165.8mb, fielddata=725/725b,
in_flight_requests=3126550/2.9mb, model_inference=0/0b, single_request=0/0b, accounting=129583700/123.5mb] 
[type=parent_circuit_breaking_exception]"}

解读:

  • [parent]父熔断,此外还有fielddata、in_flight_request,介绍见附录
  • Data too large, data for <http_request> would be 15578885702/14.3gb 这个就是上限内存(缺省是它是ES最⼤内存的90%)
  • real usage: 15578885480/14.4gb ES已经使⽤的内存
  • new bytes reserved: 222/222b 本次查询需要的内存

原因分析和解决方案

出现熔断说明当前节点 JVM 使用率过高,通过熔断保护进程不会 OOM。此时可以通过适当降低读写、清理内存等方法降低节点负载,也可以通过升级节点内存规格来提高 JVM 大小。

计算方式(父熔断,其他熔断方式类同):

腾讯云默认JVM大小为机器的50%,如节点为16C32G,则JVM默认为16G,通过

GET _cluster/settings?include_defaults&flat_settings查询熔断器配置,可以看到熔断器父熔断总限制为JVM的90%,16*0.9=14.5gb,那么如果内存不足,为了保护集群,就会产生父熔断保护集群。

如为fielddata熔断,则查看indices.breaker.fielddata.limit,如下图为20%

集群setting集群setting

常用的内存清理方法

清理 fielddata cache:

在 text 类型的字段上进行聚合和排序时会使用 fileddata 数据结构,可能占用较大内存。可以在 Kibana 界面的【Dev Tools】中使用如下命令查看索引的 fielddata 内存占用:

代码语言:javascript复制
GET/_cat/indices?v&h=index,fielddata.memory_size&s=fielddata.memory_size:desc

若 fielddata 占用内存过高,可以在 Kibana 界面的【Dev Tools】中使用如下命令清理 fielddata:

代码语言:javascript复制
POST /${fielddata占用内存较高的索引}/_cache/clear?fielddata=true

清理 segment:

每个 segment 的 FST 结构都会被加载到内存中,并且这些内存是不会被 GC 回收的。因此如果索引的 segment 数量过大,也会导致内存使用率较高。可以在 Kibana 界面的【Dev Tools】中使用如下命令查看各节点的 segment 数量和占用内存大小:

代码语言:javascript复制
GET/_cat/nodes?v&h=segments.count,segments.memory&s=segments.memory:desc

若 segment 占用内存过高,可以通过删除部分不用的索引、关闭索引,或定期合并不再更新的索引等方式缓解。

扩容集群:

如果您清理内存后,仍频繁触发熔断,说明您的集群规模已经不匹配于您的业务负载,最好的方式是扩大集群规模,具体可参考 扩容集群。

更新内核:

优先推动更新内核,根据客户使用情况来重启集群更新到最新版本的内核,会有所优化。ES内核基本上每个月都有迭代,会修复一些已知的问题。内核版本查看:

附录:

Elasticsearch 官方熔断器

父熔断器(Parent circuit breaker)

父熔断器限制所有子熔断器上使用的内存总量,当触发父熔断器熔断时,可能的日志信息如下:

代码语言:javascript复制
Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [1749436147/1.6gb], which is larger than the limit of [1622605824/1.5gb], real usage: [1749435872/1.6gb], new bytes reserved: [275/275b]

  • Field data 熔断器(Field data breaker) 当对 text 字段聚合或排序时,会产生 Field data 数据结构。Field data 熔断器会预估有多少数据被加载到内存中。当预估的数据占用内存到达 Field data 熔断器阈值时,会触发 Field data 熔断器熔断。此时可能的日志信息如下:
代码语言:javascript复制
org.elasticsearch.common.breaker.CircuitBreakingException: [fielddata] Data too large, data for [_id] would be [943928680/900.2mb], which is larger than the limit of [255606128/243.7mb]

  • In flight 请求熔断器(In flight requests circuit breaker) In flight 请求熔断器限制了在 transport 和 HTTP 层的所有当前传入的请求所使用的内存。当触发 In flight 请求熔断器时,可能的日志信息如下:
代码语言:javascript复制
[o.e.x.m.e.l.LocalExporter] [1611816935001404932] unexpected error while indexing monitoring document org.elasticsearch.xpack.monitoring.exporter.ExportException: RemoteTransportException[[1611816935001404732][9.10Elasticsearch 

0 人点赞