name is a string field (not analyzed) and group_id is an integer. Both fields can have a large cardinality.
This is the exception I see in the logs
Caused by: QueryPhaseExecutionException[Query Failed [Failed to execute main query]]; nested: CircuitBreakingException[[request] Data too large, data for [<reused_arrays>] would be larger than limit of [12769768243/11.8gb]];
at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:409)
at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:113)
at org.elasticsearch.search.SearchService.loadOrExecuteQueryPhase(SearchService.java:372)
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:385)
at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:368)
at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:365)
at org.elasticsearch.transport.TransportRequestHandler.messageReceived(TransportRequestHandler.java:33)
at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:77)
at org.elasticsearch.transport.netty.MessageChannelHandler$RequestHandler.doRun(MessageChannelHandler.java:293)
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: CircuitBreakingException[[request] Data too large, data for [<reused_arrays>] would be larger than limit of [12769768243/11.8gb]]
at org.elasticsearch.common.breaker.ChildMemoryCircuitBreaker.circuitBreak(ChildMemoryCircuitBreaker.java:97)
at org.elasticsearch.common.breaker.ChildMemoryCircuitBreaker.addEstimateBytesAndMaybeBreak(ChildMemoryCircuitBreaker.java:147)
at org.elasticsearch.common.util.BigArrays.adjustBreaker(BigArrays.java:396)
at org.elasticsearch.common.util.BigArrays.validate(BigArrays.java:433)
at org.elasticsearch.common.util.BigArrays.newByteArray(BigArrays.java:458)
at org.elasticsearch.common.util.BigArrays.resize(BigArrays.java:475)
at org.elasticsearch.common.util.BigArrays.grow(BigArrays.java:489)
at org.elasticsearch.search.aggregations.metrics.cardinality.HyperLogLogPlusPlus.ensureCapacity(HyperLogLogPlusPlus.java:197)
at org.elasticsearch.search.aggregations.metrics.cardinality.HyperLogLogPlusPlus.collect(HyperLogLogPlusPlus.java:230)
at org.elasticsearch.search.aggregations.metrics.cardinality.CardinalityAggregator$DirectCollector.collect(CardinalityAggregator.java:203)
at org.elasticsearch.search.aggregations.LeafBucketCollector$3.collect(LeafBucketCollector.java:73)
at org.elasticsearch.search.aggregations.bucket.BucketsAggregator.collectExistingBucket(BucketsAggregator.java:80)
at org.elasticsearch.search.aggregations.bucket.terms.GlobalOrdinalsStringTermsAggregator$2.collect(GlobalOrdinalsStringTermsAggregator.java:130)
at org.elasticsearch.search.aggregations.LeafBucketCollector.collect(LeafBucketCollector.java:88)
at org.apache.lucene.search.MultiCollector$MultiLeafCollector.collect(MultiCollector.java:174)
at org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:221)
at org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:172)
at org.apache.lucene.search.BulkScorer.score(BulkScorer.java:39)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:821)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:535)
at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:384)
... 12 more
On a first glance at that stack trace it looks like it isn't using breadth_first collect mode and it's unclear why not.
Can you supply the mapping and a minimal example of a doc?
I am also seeing fielddata being used up for the name field which is strange since 2.x, doc values are enabled by default. Even a simple terms aggregations causes the fielddata to be consumed.
Thanks just tried that mapping/doc/query and it definitely uses breadth_first on the current master branch.
Are you sure that your example query is related to that stack trace? Can you supply the full JSON of the response you get back from that query?
@Mark_Harwood Unfortunately we time out after 10 seconds so we are not seeing anything in the response. I will try again with a longer timeout to see if I get anything.
Do you mind sharing how you verified it ?
Also do you happen to why field data is getting consumed for the name field ?
Actually I looked at the slow log and I found that the collect mode wasn't applied for one of the queries, which explains why it went OOM. Thanks a lot for your help.
I've re-tested this on a separate cluster by deleting everything and recreating the mapping and still seems to be consuming field data. We have a fixed set of indexes and don't use templates too. Any ideas on how I can debug this further ?
@Mark_Harwood Appreciate your help ! I replicated the above setup exactly and the _cat/fielddata API reported no field data being consumed. However when I indexed few more documents (7 more in this case) I see one node showing 424b. Although it shouldn't make a different its worth mentioning that I am currently running 2.4.0 version.
Hmm. I got a similar thing. Repeated additions saw the fielddata size drop to zero, presumably as a result of some merge operations.
It may be an oddity of the reporting logic.
Presumably on your large cluster you're not seeing very large (as in GBs) of fielddata usage?
This should give you docvalues sizes: GET /test/_stats/segments
Unfortunately we are, whenever we issue any aggregation in production it takes up to ~ 2GB on some nodes. It does drop back considerably after a few mins.
Also when I update each field in the mapping to have
"fielddata": {
"format": "disabled"
}
the aggregation fails with the error message
"Field data loading is forbidden on [name]"
This to me seems to suggest that fielddata is actually being used.
_stats/segments does show small values for doc_values_memory_in_bytes which is probably a sign that doc values are also being used.
Do you mind trying again by disabling fielddata on your setup and see if you get the same exception ? I just tried on the test index and it failed with the same exception.
I think the reason that you see field data usage being used and the search request fails when you disable field data, is that the terms aggregation uses global ordinals [1], and that is being kept around in field data cache. However global ordinals are very well compressed and thus should be small. How many unique values are in the name field?
Can you try setting the execution_hint to map on the terms aggregation and check if you can execute the search request without running into the error that field data loading has been disabled? This is just to check if what I'm saying is correct. In production using an execution mode that uses global ordinals results in general in better performance.
@mvg Thanks ! We have multiple indexes and for a given index there can be tens of millions of unique values.
You were right, when I try setting the execution_hit it doesn't consume any fielddata.
That may be the case why field data usage is so high in your case. On its own this shouldn't be an issue. Do you know on how many shards you execute the search request? It maybe beneficial to reduce the number of shards, which can reduce the size global ordinals take in the field data cache across your cluster. Via the cat shards api you can check the number of shards exist for the indices you query and figure out per shard the global ordinals usage in field data cache. (assuming that name is the only field you're using now)
In case your data is time based data then in 5.0 there is a new shrink api [1] that makes reducing the number of shards trivial (without reindexing).
Thanks a lot for the details. I have a few more follow up questions
Does the per field memory usage returned _cat/fielddata include global ordinals ?
Since doc values is disk based, what does doc_values_memory_in_bytes give ?
Is there a way to measure the space consumed by global ordinals ?
Also I see conflicting things in the documentation related to fielddata and aggregations, [1] seems to suggest that fielddata wont be loaded but [2] says other wise. Is it possible to eagerly load global originals without triggering field data load.
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.