今天在向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%