I am testing the msearch capability on the rally's geonames set with quite a lot of basic match queries (1500) and even though each query is very fast I have noticed that the more shards I set for my index, the longer the whole msearch takes... no matter how many nodes/machines I set up in the cluster.
Thread pool might be a bottleneck on a single machine but I would have expected some performance gain with horizontal scaling.
Populate them with the rally's geonames data set (I had actually let rally create the first index and used the wonderful reindex API to populate the others)
Elasticsearch has several limits in place that could explain this behavior. First of all, the number of concurrent searches is limited based on the number of nodes and the size of the search thread pool (see also max_concurrent_searches in the msearch docs). After a node has received an msearch requests, it sends each query individually to a node in the cluster (and respecting max_concurrent_searches). That node will coordinate the search request and will query individual shards. In order to avoid overwhelming the cluster there is another limit per query in place which allows at most 256 or number of nodes * default number of shards (5) concurrent shard requests whichever of those two numbers is smaller (see source code). To be clear: the default number of shards is the out-of-the-box default, not the configured default for that index. In the case of a three node cluster it would query 3 (nodes) * 5 (shards) = 15 shards at most per search request.
As the geonames index is rather small (around 6GB), I guess the search time is dominated by:
Wait time spent in the search queue of the individual nodes
Wait time for results to arrive at the coordinating node
and finally also the limit of maximum number of concurrent shard requests.
I think it could make sense to retry this experiment with a much larger index.
Is there any config to limit MaxConcurrentShardRequests? because in our case 256 is still to much.
Also we use ES 2.4 and It seems that this limit was added in ES 6.x. So there was no limit before that, yeah?
Hi Daniel and thanks a lot for the answer and details! It fits all my tests : I had first tried to play with the max_concurrent_searches setting (this defaultMaxConcurrentSearches looked pretty interesting) but without any success... which kind of determined the coordinating node as the bottleneck. Then splitting the msearch and sending each part to different client nodes helped.
Oh btw, is there any better and finer way to follow a threadpool than watch -n 0.1 ?
I suppose you mean by that, that you call the node stats API periodically? That's the usual approach to monitor thread pool statistics from the command line. You can limit node stats to thread pool statistics e.g. by issuing curl -X GET "es_host:9200/_nodes/stats/thread_pool?pretty" and use a tool like jq to only show the fields you're interested in. Alternatively, you can use X-Pack monitoring to view thread pool statistics over time.
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.