今天在向ES导入数据,通过kibana进行查询时出现 [circuit_breaking_exception] [parent] Data too large, data for [<http_request>] would be [1003569608/957mb]
错误,一顿google解决了这个问题,记录一下。
kibana的异常日志如下:
log [15:53:41.570] [error][status][plugin:reporting@7.6.1] Status changed from red to red - [circuit_breaking_exception] [parent] Data too large, data for [<http_request>] would be [1003569608/957mb], which is larger than the limit of [986061209/940.3mb], real usage: [1003569608/957mb], new bytes reserved: [0/0b], usages [request=0/0b, fielddata=6732/6.5kb, in_flight_requests=452608/442kb, accounting=367288473/350.2mb], with { bytes_wanted=1003569608 & bytes_limit=986061209 & durability="PERMANENT" }
环境信息:
Windows 10(Build 18363) + JDK 13.0.2 Elasticsearch 7.6.1 + Logstash 7.6.1 + Kibana 7.6.1 + Metricbeat 7.6.1
indices.breaker.fielddata.limit
、 indices.breaker.request.limit
和 indices.breaker.total.limit
fielddata断路器默认设置为jvm堆内存的60%作为上限,request断路器默认设置为jvm堆内存的40%,total的值保证request断路器和fielddata断路器两者组合起来不超过jvm堆内存的70%。断路器的限制可以在文件config/elasticsearch.yml中指定,也可以动态更新一个正在运行的集群。
针对"Data too large"这个报错,我们要么清理缓存、要么增大内存
curl -XPOST 'http://localhost:9200/fdns/_cache/clear?fielddata=true'
返回结果为:
{"_shards":{"total":10,"successful":5,"failed":0}}
调用UPDATE _cluster/settings设置indices.fielddata.cache.size参数来限制fileddata缓存不要占用过大的jvm堆内存。设置方法如下:
curl -XPUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d '{ "persistent" : { "indices.breaker.fielddata.limit" : "40%" } }'
将field data调整为40%后查看kibana服务正常,返回值如下:
{ "acknowledged": true, "persistent": { "indices": { "breaker": { "fielddata": { "limit": "40%" } } } }, "transient": {} }
*如果修改field data值为40%仍然报错,建议设置更小的值试试。
默认ES的jvm堆内存大小设置为1G,这里我们修改为8G,在config/jvm.options中修改:
-Xms8g -Xmx8g
fielddata值是用来存储查询信息的缓存,如果你查询一个新的信息时fielddata中未缓存此信息,查询结果的大小超过了field data的使用空间大小,其他的值将会被回收从而获得足够的空间。
默认情况下fielddata的缓存大小设置为unbounded,即Elasticsearch 永远都不会从fielddata中回收数据。这个默认设置是刻意设计成这样的,fielddata并不是临时缓存,它是驻留内存里的数据结构,必须可以快速执行访问,而且构建它的代价十分高昂。如果每个请求都重载数据,性能会十分糟糕。因此我们要为fielddata设置合适的值来优化Elasticsearch并非用这个设置解决内存不够用的问题。
可以通过调节indices.fielddata.cache.size
的值为fielddata分配的堆空间大小,修改config/elasticsearch.yml文件可以实现配置,最佳实践配置如下:
# 避免发生OOM indices.breaker.total.limit: 70% # 最久未使用的 fielddata 会被回收 indices.fielddata.cache.size: 25% # fielddata 断路器 indices.breaker.fielddata.limit: 40% # request 断路器 indices.breaker.request.limit: 40%