34
34
35
35
import org .apache .logging .log4j .LogManager ;
36
36
import org .apache .logging .log4j .Logger ;
37
- import org .opensearch .cluster .metadata .WeightedRoutingMetadata ;
38
37
import org .opensearch .cluster .node .DiscoveryNode ;
39
38
import org .opensearch .cluster .node .DiscoveryNodes ;
40
39
import org .opensearch .common .Nullable ;
63
62
import java .util .Set ;
64
63
import java .util .function .Predicate ;
65
64
import java .util .stream .Collectors ;
66
- import java .util .stream .Stream ;
67
65
68
66
import static java .util .Collections .emptyMap ;
69
67
@@ -96,8 +94,8 @@ public class IndexShardRoutingTable implements Iterable<ShardRouting> {
96
94
private volatile Map <AttributesKey , AttributesRoutings > initializingShardsByAttributes = emptyMap ();
97
95
private final Object shardsByAttributeMutex = new Object ();
98
96
private final Object shardsByWeightMutex = new Object ();
99
- private volatile Map <WeightedRoutingKey , List < ShardRouting > > activeShardsByWeight = emptyMap ();
100
- private volatile Map <WeightedRoutingKey , List < ShardRouting > > initializingShardsByWeight = emptyMap ();
97
+ private volatile Map <WeightedRoutingKey , WeightedShardRoutings > activeShardsByWeight = emptyMap ();
98
+ private volatile Map <WeightedRoutingKey , WeightedShardRoutings > initializingShardsByWeight = emptyMap ();
101
99
102
100
private static final Logger logger = LogManager .getLogger (IndexShardRoutingTable .class );
103
101
@@ -249,7 +247,7 @@ public List<ShardRouting> assignedShards() {
249
247
return this .assignedShards ;
250
248
}
251
249
252
- public Map <WeightedRoutingKey , List < ShardRouting > > getActiveShardsByWeight () {
250
+ public Map <WeightedRoutingKey , WeightedShardRoutings > getActiveShardsByWeight () {
253
251
return activeShardsByWeight ;
254
252
}
255
253
@@ -338,23 +336,7 @@ public ShardIterator activeInitializingShardsWeightedIt(
338
336
// append shards for attribute value with weight zero, so that shard search requests can be tried on
339
337
// shard copies in case of request failure from other attribute values.
340
338
if (isFailOpenEnabled ) {
341
- try {
342
- Stream <String > keys = weightedRouting .weights ()
343
- .entrySet ()
344
- .stream ()
345
- .filter (entry -> entry .getValue ().intValue () == WeightedRoutingMetadata .WEIGHED_AWAY_WEIGHT )
346
- .map (Map .Entry ::getKey );
347
- keys .forEach (key -> {
348
- ShardIterator iterator = onlyNodeSelectorActiveInitializingShardsIt (weightedRouting .attributeName () + ":" + key , nodes );
349
- while (iterator .remaining () > 0 ) {
350
- ordered .add (iterator .nextOrNull ());
351
- }
352
- });
353
- } catch (IllegalArgumentException e ) {
354
- // this exception is thrown by {@link onlyNodeSelectorActiveInitializingShardsIt} in case count of shard
355
- // copies found is zero
356
- logger .debug ("no shard copies found for shard id [{}] for node attribute with weight zero" , shardId );
357
- }
339
+ ordered .addAll (activeInitializingShardsWithoutWeights (weightedRouting , nodes , defaultWeight ));
358
340
}
359
341
360
342
return new PlainShardIterator (shardId , ordered );
@@ -378,6 +360,18 @@ private List<ShardRouting> activeInitializingShardsWithWeights(
378
360
return orderedListWithDistinctShards ;
379
361
}
380
362
363
+ private List <ShardRouting > activeInitializingShardsWithoutWeights (
364
+ WeightedRouting weightedRouting ,
365
+ DiscoveryNodes nodes ,
366
+ double defaultWeight
367
+ ) {
368
+ List <ShardRouting > ordered = new ArrayList <>(getActiveShardsWithoutWeight (weightedRouting , nodes , defaultWeight ));
369
+ if (!allInitializingShards .isEmpty ()) {
370
+ ordered .addAll (getInitializingShardsWithoutWeight (weightedRouting , nodes , defaultWeight ));
371
+ }
372
+ return ordered .stream ().distinct ().collect (Collectors .toList ());
373
+ }
374
+
381
375
/**
382
376
* Returns a list containing shard routings ordered using weighted round-robin scheduling.
383
377
*/
@@ -949,20 +943,55 @@ public int hashCode() {
949
943
}
950
944
}
951
945
946
+ @ PublicApi (since = "2.14.0" )
947
+ public static class WeightedShardRoutings {
948
+ private final List <ShardRouting > shardRoutingsWithWeight ;
949
+ private final List <ShardRouting > shardRoutingWithoutWeight ;
950
+
951
+ public WeightedShardRoutings (List <ShardRouting > shardRoutingsWithWeight , List <ShardRouting > shardRoutingWithoutWeight ) {
952
+ this .shardRoutingsWithWeight = Collections .unmodifiableList (shardRoutingsWithWeight );
953
+ this .shardRoutingWithoutWeight = Collections .unmodifiableList (shardRoutingWithoutWeight );
954
+ }
955
+
956
+ public List <ShardRouting > getShardRoutingsWithWeight () {
957
+ return shardRoutingsWithWeight ;
958
+ }
959
+
960
+ public List <ShardRouting > getShardRoutingWithoutWeight () {
961
+ return shardRoutingWithoutWeight ;
962
+ }
963
+ }
964
+
952
965
/**
953
966
* *
954
967
* Gets active shard routing from memory if available, else calculates and put it in memory.
955
968
*/
956
969
private List <ShardRouting > getActiveShardsByWeight (WeightedRouting weightedRouting , DiscoveryNodes nodes , double defaultWeight ) {
957
970
WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
958
- List <ShardRouting > shardRoutings = activeShardsByWeight .get (key );
959
- if (shardRoutings == null ) {
960
- synchronized (shardsByWeightMutex ) {
961
- shardRoutings = shardsOrderedByWeight (activeShards , weightedRouting , nodes , defaultWeight );
962
- activeShardsByWeight = new MapBuilder ().put (key , shardRoutings ).immutableMap ();
963
- }
971
+ if (activeShardsByWeight .get (key ) == null ) {
972
+ populateActiveShardWeightsMap (weightedRouting , nodes , defaultWeight );
973
+ }
974
+ return activeShardsByWeight .get (key ).getShardRoutingsWithWeight ();
975
+ }
976
+
977
+ private List <ShardRouting > getActiveShardsWithoutWeight (WeightedRouting weightedRouting , DiscoveryNodes nodes , double defaultWeight ) {
978
+ WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
979
+ if (activeShardsByWeight .get (key ) == null ) {
980
+ populateActiveShardWeightsMap (weightedRouting , nodes , defaultWeight );
981
+ }
982
+ return activeShardsByWeight .get (key ).getShardRoutingWithoutWeight ();
983
+ }
984
+
985
+ private void populateActiveShardWeightsMap (WeightedRouting weightedRouting , DiscoveryNodes nodes , double defaultWeight ) {
986
+ WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
987
+ List <ShardRouting > weightedRoutings = shardsOrderedByWeight (activeShards , weightedRouting , nodes , defaultWeight );
988
+ List <ShardRouting > nonWeightedRoutings = activeShards .stream ()
989
+ .filter (shard -> !weightedRoutings .contains (shard ))
990
+ .collect (Collectors .toUnmodifiableList ());
991
+ synchronized (shardsByWeightMutex ) {
992
+ activeShardsByWeight = new MapBuilder ().put (key , new WeightedShardRoutings (weightedRoutings , nonWeightedRoutings ))
993
+ .immutableMap ();
964
994
}
965
- return shardRoutings ;
966
995
}
967
996
968
997
/**
@@ -971,14 +1000,34 @@ private List<ShardRouting> getActiveShardsByWeight(WeightedRouting weightedRouti
971
1000
*/
972
1001
private List <ShardRouting > getInitializingShardsByWeight (WeightedRouting weightedRouting , DiscoveryNodes nodes , double defaultWeight ) {
973
1002
WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
974
- List <ShardRouting > shardRoutings = initializingShardsByWeight .get (key );
975
- if (shardRoutings == null ) {
976
- synchronized (shardsByWeightMutex ) {
977
- shardRoutings = shardsOrderedByWeight (activeShards , weightedRouting , nodes , defaultWeight );
978
- initializingShardsByWeight = new MapBuilder ().put (key , shardRoutings ).immutableMap ();
979
- }
1003
+ if (initializingShardsByWeight .get (key ) == null ) {
1004
+ populateInitializingShardWeightsMap (weightedRouting , nodes , defaultWeight );
1005
+ }
1006
+ return initializingShardsByWeight .get (key ).getShardRoutingsWithWeight ();
1007
+ }
1008
+
1009
+ private List <ShardRouting > getInitializingShardsWithoutWeight (
1010
+ WeightedRouting weightedRouting ,
1011
+ DiscoveryNodes nodes ,
1012
+ double defaultWeight
1013
+ ) {
1014
+ WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
1015
+ if (initializingShardsByWeight .get (key ) == null ) {
1016
+ populateInitializingShardWeightsMap (weightedRouting , nodes , defaultWeight );
1017
+ }
1018
+ return initializingShardsByWeight .get (key ).getShardRoutingWithoutWeight ();
1019
+ }
1020
+
1021
+ private void populateInitializingShardWeightsMap (WeightedRouting weightedRouting , DiscoveryNodes nodes , double defaultWeight ) {
1022
+ WeightedRoutingKey key = new WeightedRoutingKey (weightedRouting );
1023
+ List <ShardRouting > weightedRoutings = shardsOrderedByWeight (allInitializingShards , weightedRouting , nodes , defaultWeight );
1024
+ List <ShardRouting > nonWeightedRoutings = allInitializingShards .stream ()
1025
+ .filter (shard -> !weightedRoutings .contains (shard ))
1026
+ .collect (Collectors .toUnmodifiableList ());
1027
+ synchronized (shardsByWeightMutex ) {
1028
+ initializingShardsByWeight = new MapBuilder ().put (key , new WeightedShardRoutings (weightedRoutings , nonWeightedRoutings ))
1029
+ .immutableMap ();
980
1030
}
981
- return shardRoutings ;
982
1031
}
983
1032
984
1033
/**
0 commit comments