1717import org .elasticsearch .action .search .SearchShardsResponse ;
1818import org .elasticsearch .action .support .TransportActions ;
1919import org .elasticsearch .cluster .node .DiscoveryNode ;
20+ import org .elasticsearch .cluster .node .DiscoveryNodeRole ;
2021import org .elasticsearch .common .util .concurrent .ConcurrentCollections ;
2122import org .elasticsearch .compute .operator .DriverProfile ;
2223import org .elasticsearch .compute .operator .FailureCollector ;
3536
3637import java .util .ArrayList ;
3738import java .util .Collections ;
39+ import java .util .Comparator ;
3840import java .util .HashMap ;
3941import java .util .IdentityHashMap ;
4042import java .util .Iterator ;
43+ import java .util .LinkedHashMap ;
4144import java .util .List ;
4245import java .util .Map ;
4346import java .util .Queue ;
5255 * and executing these computes on the data nodes.
5356 */
5457abstract class DataNodeRequestSender {
58+
59+ private static final String [] NODE_QUERY_ORDER = new String [] {
60+ DiscoveryNodeRole .DATA_HOT_NODE_ROLE .roleName (),
61+ DiscoveryNodeRole .DATA_WARM_NODE_ROLE .roleName (),
62+ DiscoveryNodeRole .DATA_COLD_NODE_ROLE .roleName (),
63+ DiscoveryNodeRole .DATA_FROZEN_NODE_ROLE .roleName () };
64+
5565 private final TransportService transportService ;
5666 private final Executor esqlExecutor ;
5767 private final CancellableTask rootTask ;
@@ -97,12 +107,35 @@ final void startComputeOnDataNodes(
97107 nodePermits .putIfAbsent (node , new Semaphore (1 ));
98108 }
99109 }
100- pendingShardIds .addAll (targetShards . shards . keySet ( ));
110+ pendingShardIds .addAll (order ( targetShards ));
101111 trySendingRequestsForPendingShards (targetShards , computeListener );
102112 }
103113 }, listener ::onFailure ));
104114 }
105115
116+ private static List <ShardId > order (TargetShards targetShards ) {
117+ var ordered = new ArrayList <>(targetShards .shards .keySet ());
118+ ordered .sort (Comparator .comparingInt (shardId -> nodeOrder (targetShards .getShard (shardId ).remainingNodes )));
119+ return ordered ;
120+ }
121+
122+ private static int nodeOrder (List <DiscoveryNode > nodes ) {
123+ if (nodes .isEmpty ()) {
124+ return Integer .MAX_VALUE ;
125+ }
126+ // assumes all shard nodes have same roles
127+ var node = nodes .getFirst ();
128+ if (node .hasRole (DiscoveryNodeRole .DATA_CONTENT_NODE_ROLE .roleName ()) || node .hasRole (DiscoveryNodeRole .DATA_ROLE .roleName ())) {
129+ return 0 ;
130+ }
131+ for (int i = 0 ; i < NODE_QUERY_ORDER .length ; i ++) {
132+ if (node .hasRole (NODE_QUERY_ORDER [i ])) {
133+ return i ;
134+ }
135+ }
136+ return NODE_QUERY_ORDER .length ;
137+ }
138+
106139 private void trySendingRequestsForPendingShards (TargetShards targetShards , ComputeListener computeListener ) {
107140 changed .set (true );
108141 final ActionListener <Void > listener = computeListener .acquireAvoid ();
@@ -243,17 +276,11 @@ TargetShard getShard(ShardId shardId) {
243276 /**
244277 * (Remaining) allocated nodes of a given shard id and its alias filter
245278 */
246- record TargetShard (ShardId shardId , List <DiscoveryNode > remainingNodes , AliasFilter aliasFilter ) {
247-
248- }
279+ record TargetShard (ShardId shardId , List <DiscoveryNode > remainingNodes , AliasFilter aliasFilter ) {}
249280
250- record NodeRequest (DiscoveryNode node , List <ShardId > shardIds , Map <Index , AliasFilter > aliasFilters ) {
281+ record NodeRequest (DiscoveryNode node , List <ShardId > shardIds , Map <Index , AliasFilter > aliasFilters ) {}
251282
252- }
253-
254- private record ShardFailure (boolean fatal , Exception failure ) {
255-
256- }
283+ private record ShardFailure (boolean fatal , Exception failure ) {}
257284
258285 /**
259286 * Selects the next nodes to send requests to. Limits to at most one outstanding request per node.
@@ -262,7 +289,7 @@ private record ShardFailure(boolean fatal, Exception failure) {
262289 */
263290 private List <NodeRequest > selectNodeRequests (TargetShards targetShards ) {
264291 assert sendingLock .isHeldByCurrentThread ();
265- final Map <DiscoveryNode , List <ShardId >> nodeToShardIds = new HashMap <>();
292+ final Map <DiscoveryNode , List <ShardId >> nodeToShardIds = new LinkedHashMap <>();
266293 final Iterator <ShardId > shardsIt = pendingShardIds .iterator ();
267294 while (shardsIt .hasNext ()) {
268295 ShardId shardId = shardsIt .next ();
@@ -288,16 +315,17 @@ private List<NodeRequest> selectNodeRequests(TargetShards targetShards) {
288315 }
289316 }
290317 final List <NodeRequest > nodeRequests = new ArrayList <>(nodeToShardIds .size ());
291- for (var e : nodeToShardIds .entrySet ()) {
292- List <ShardId > shardIds = e .getValue ();
318+ for (var entry : nodeToShardIds .entrySet ()) {
319+ var node = entry .getKey ();
320+ var shardIds = entry .getValue ();
293321 Map <Index , AliasFilter > aliasFilters = new HashMap <>();
294322 for (ShardId shardId : shardIds ) {
295323 var aliasFilter = targetShards .getShard (shardId ).aliasFilter ;
296324 if (aliasFilter != null ) {
297325 aliasFilters .put (shardId .getIndex (), aliasFilter );
298326 }
299327 }
300- nodeRequests .add (new NodeRequest (e . getKey () , shardIds , aliasFilters ));
328+ nodeRequests .add (new NodeRequest (node , shardIds , aliasFilters ));
301329 }
302330 return nodeRequests ;
303331 }
0 commit comments