异常
{
"error" : {
"root_cause" : [
{
"type" : "circuit_breaking_exception",
"reason" : "[parent] Data too large, data for [<http_request>] would be [115813528/110.4mb], which is larger than the limit of [115553075/110.1mb], real usage: [115813528/110.4mb], new bytes reserved: [0/0b]",
"bytes_wanted" : 115813528,
"bytes_limit" : 115553075,
"durability" : "PERMANENT"
}
],
"type" : "circuit_breaking_exception",
"reason" : "[parent] Data too large, data for [<http_request>] would be [115813528/110.4mb], which is larger than the limit of [115553075/110.1mb], real usage: [115813528/110.4mb], new bytes reserved: [0/0b]",
"bytes_wanted" : 115813528,
"bytes_limit" : 115553075,
"durability" : "PERMANENT"
},
"status" : 429
再尝试其他查询也是如此。经排查,原来是ES默认的缓存设置让缓存区只进不出引起的,具体分析一下。
参数 indices.fielddata.cache.size 控制有多少堆内存是分配给fielddata。当你执行一个查询需要访问新的字段值的时候,将会把值加载到内存,然后试着把它们加入到fielddata。如果结果的fielddata大小超过指定的大小 ,为了腾出空间,别的值就会被驱逐出去。
默认情况下,这个参数设置的是无限制 — Elasticsearch将永远不会把数据从fielddata里替换出去。
indices.fielddata.cache.size 配置fieldData的Cache大小,可以配百分比也可以配一个准确的数值。cache到达约定的内存大小时会自动清理,驱逐一部分FieldData数据以便容纳新数据。默认值为unbounded无限。
indices.fielddata.cache.expire用于约定多久没有访问到的数据会被驱逐,默认值为-1,即无限。expire配置不推荐使用,按时间驱逐数据会大量消耗性能。而且这个设置在不久之后的版本中将会废弃。
看来,Data too large异常就是由于fielddata.cache的默认值为unbounded导致的了。
解决办法:
PUT http://127.0.0.1:9200/_cluster/settings
(application/json)
{
"persistent" : {
"indices.breaker.fielddata.limit" : "40%"
}
}
结果
{
"acknowledged": true,
"persistent": {
"indices": {
"breaker": {
"fielddata": {
"limit": "40%"
}
}
}
},
"transient": {}
}