With a wide ES request, I get
Failed to execute [ org.elasticsearch.action.search.SearchRequest@59e634e2 ] lastShard [true] org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution (queue capacity 1000) on org.elasticsearch.search. action.SearchServiceTransportAction$23@75bd024b at org.elasticsearch.common.util.concurrent.EsAbortPolicy.rejectedExecution(EsAbortPolicy.java:62) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369) at org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor.execute(EsThreadPoolExecutor.java:79) at org.elasticsearch.search.action.SearchServiceTransportAction.execute(SearchServiceTransportAction.java:551) at org.elasticsearch.search.action.SearchServiceTransportAction.sendExecuteQuery(SearchServiceTransportAction.java:228) at org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction$AsyncAction.sendExecuteFirstPhase(TransportSearchQueryThenFetchAction.java:83)
on a very regular basis.
Now my plan is to pause query requests until the queue load drops below x . You can request a client for stats
client.admin().cluster().threadPool().stats().iterator();
But since my client is not a given node (I suppose why), I return queue=0 , and the node server throws the above error.
I know why this works, and I know how to update the parameter, but it just postpones this error and creates others ...
How to set cluster nodes that their loading in the queue?
PS: I use Java Api
What I tried without a request is an empty string indicating another attempt, unless otherwise indicated
//Nodes stats final NodesStatsResponse nodesStatsResponse = client.admin().cluster().prepareNodesStats().execute().actionGet(); final NodeStats nodeStats = nodesStatsResponse.getNodes()[0]; final String nodeId = nodeStats.getNode().getId(); // need this later on // same as before, but with explicit NodesStatsRequest (with id) final NodesStatsResponse response = client.admin().cluster().nodesStats(new NodesStatsRequest(nodeId)).actionGet(); final NodeStats[] nodeStats2 = response.getNodes(); for (NodeStats nodeStats3 : nodeStats2) { Stats stats = nodeStats3.getThreadPool().iterator().next(); } // Cluster? final ClusterStatsRequest clusterStatsRequest = new ClusterStatsRequestBuilder(client.admin().cluster()).request(); final ClusterStatsResponse clusterStatsResponse = client.admin().cluster().clusterStats(clusterStatsRequest).actionGet(); final ClusterStatsNodes clusterStatsNodes = clusterStatsResponse.getNodesStats(); // Nodes info? final NodesInfoResponse infoResponse = client.admin().cluster().nodesInfo(new NodesInfoRequest(nodeId)).actionGet();// here final NodeInfo[] nodeInfos = infoResponse.getNodes(); for (final NodeInfo nodeInfo : nodeInfos) { final ThreadPoolInfo info = nodeInfo.getThreadPool(); final Iterator<Info> infoIterator = info.iterator(); while (infoIterator.hasNext()) { final Info realInfo = infoIterator.next(); SizeValue sizeValue = realInfo.getQueueSize(); // is no == null, then (ΒΏhappens?, was expecting a nullpointer, but Thread disappeared) if (sizeValue == null) continue; // normal queue size, no load (oddly found 1000 (expected), and one of 200 in one node?) final long queueSize = sizeValue.getSingles(); } }
The problem is that some processes must be called instantly (for example, user queries), while others may wait if the database is too busy (background processes). Preferably, I would assign a certain part of the queue to processes that are on immediate requests, and the other part to background processes (but I did not see this option).
Update It seems that I did not expect that you could get a request overload with a single bulk request when the total amount of individual requests exceeds 1000 (when x fragments or indexes x are divided by 1000 / x for the number of searches). So bulking ,, not option if you cannot make a single request. Therefore, when you aim at 700 search results right away (taking into account the above statement), you need to know if there are more than 300 elements in the queue, since then it will throw things.
Summarizing:
Suppose the load per call is maximum bulkrequest , so I cannot combine requests. How then can I start pausing requests until . Elasticsearch begins to throw the above exception. So I can pause part of my application, but not another? If I know that the queue is half full, say, the background process should sleep for a while. How to find out (approximate) queue loading?