@DavidTurner Thanks for looking this over so thoroughly.
The docker-compose configuration is missing from your description of how to reproduce this. In particular, in your OP you said that in the 2-node case you restricted each node to only have 4 search threads, but it is not clear how you're applying that restriction.
Sorry about forgetting the docker-compose.yml. Here it is.
In the benchmark I just kept 8 search threads for the 2-node case. I figured there's no harm in that since there are only 4 shards that the search threads could be operating on, hence max 4 threads running at any given time.
Elasticsearch has a lot of threads in PARKED
state simply because the client isn't giving them any work to do. You're suffering from Amdahl's law: the workload is mostly sequential, so increasing the width of the parallel part doesn't help much.
Ok, so it seems like the "hunch" I described in my notebook is at least part of the explanation.
Running this on your development laptop is another of those deadly sins. I tried your code on a more realistic production machine and observed essentially no difference whether the index was restricted to a single node or was spread across two:
I just tried it out on an EC2 c5.4xlarge and got these results:
- 1 master node, 1 data node, 1 shard: 258 queries/second
- 1 master node, 1 data node, 8 shards: 274 queries/second
- 1 master node, 2 data nodes, 8 shards (4 per node): 318 queries/second
Here is the updated notebook
I tried it again with 1M docs on the c5.4xlarge:
- 1 master node, 1 data node, 1 shard: 89 queries/second
- 1 master node, 1 data node, 8 shards: 132 queries/second
- 1 master node, 2 data nodes, 8 shards (4 per node): 157 queries/second
Here is the updated notebook
Maybe there's something peculiar about my docker-compose setup?
It's best not to "roll your own" when it comes to benchmarking, it's just too easy to fall into traps like this. We recommend Rally instead.
FWIW, I installed esrally and spent about an hour trying to figure out how to make it use my local Elasticsearch cluster. It somehow kept spinning up its own ES, which I guess is a nice default in general, but got in the way here. I'd appreciate any pointers for how I can check this specific behavior with Rally.