Skip to content

Commit 0e6ec7e

Browse files
nicktindallywangd
authored andcommitted
Always prefer YES over NOT_PREFERRED when allocating unassigned shards (elastic#138464)
1 parent fcb0b13 commit 0e6ec7e

File tree

3 files changed

+66
-28
lines changed

3 files changed

+66
-28
lines changed

docs/changelog/138464.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 138464
2+
summary: Always prefer YES over NOT_PREFERRED when allocating unassigned shards
3+
area: Allocation
4+
type: bug
5+
issues: []

server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,10 +1416,6 @@ private AllocateUnassignedDecision decideAllocateUnassigned(final ProjectIndex i
14161416

14171417
// weight of this index currently on the node
14181418
float currentWeight = weightFunction.calculateNodeWeightWithIndex(this, node, index);
1419-
// moving the shard would not improve the balance, and we are not in explain mode, so short circuit
1420-
if (currentWeight > minWeight && explain == false) {
1421-
continue;
1422-
}
14231419

14241420
Decision currentDecision = allocation.deciders().canAllocate(shard, node.getRoutingNode(), allocation);
14251421
if (explain) {

server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocatorTests.java

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.elasticsearch.cluster.routing.ShardRouting;
3737
import org.elasticsearch.cluster.routing.ShardRoutingState;
3838
import org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision;
39-
import org.elasticsearch.cluster.routing.allocation.AllocationService;
4039
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
4140
import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator.Balancer.PrioritiseByShardWriteLoadComparator;
4241
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider;
@@ -1165,44 +1164,54 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing
11651164
}
11661165
};
11671166

1168-
final var allocationService = new MockAllocationService(
1169-
new AllocationDeciders(List.of(notPreferredDecider)),
1170-
new TestGatewayAllocator(),
1171-
new BalancedShardsAllocator(BalancerSettings.DEFAULT, TEST_WRITE_LOAD_FORECASTER, new NodeNameDrivenBalancingWeightsFactory()),
1172-
() -> ClusterInfo.EMPTY,
1173-
SNAPSHOT_INFO_SERVICE_WITH_NO_SHARD_SIZES
1174-
);
1167+
final var allocationDeciders = new AllocationDeciders(List.of(notPreferredDecider));
1168+
final var balancingWeightsFactory = new NodeNameDrivenBalancingWeightsFactory();
11751169

11761170
// No allocation when NO
1177-
assertUnassigned(allocationService, shuffledList("no"));
1171+
assertUnassigned(allocationDeciders, balancingWeightsFactory, shuffledList("no"));
11781172
// No allocation when THROTTLE
1179-
assertUnassigned(allocationService, shuffledList("throttle"));
1173+
assertUnassigned(allocationDeciders, balancingWeightsFactory, shuffledList("throttle"));
11801174
// NOT_PREFERRED when no other choice
1181-
assertAssignedTo(allocationService, "not-preferred", shuffledList("not-preferred"));
1175+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "not-preferred", shuffledList("not-preferred"));
11821176
// NOT_PREFERRED over NO
1183-
assertAssignedTo(allocationService, "not-preferred", shuffledList("not-preferred", "no"));
1177+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "not-preferred", shuffledList("not-preferred", "no"));
11841178
// THROTTLE (No allocation) over NOT_PREFERRED/NO
1185-
assertUnassigned(allocationService, shuffledList("throttle", "not-preferred", "no"));
1179+
assertUnassigned(allocationDeciders, balancingWeightsFactory, shuffledList("throttle", "not-preferred", "no"));
11861180
// THROTTLE (No allocation) over NOT_PREFERRED
1187-
assertUnassigned(allocationService, shuffledList("throttle", "not-preferred"));
1181+
assertUnassigned(allocationDeciders, balancingWeightsFactory, shuffledList("throttle", "not-preferred"));
11881182
// YES over THROTTLE/NO/NOT_PREFERRED
1189-
assertAssignedTo(allocationService, "yes", shuffledList("not-preferred", "yes", "throttle", "no"));
1183+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "yes", shuffledList("not-preferred", "yes", "throttle", "no"));
1184+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "yes-high", shuffledList("not-preferred-low", "yes-high"));
11901185
// prioritize YES/THROTTLE by weight
1191-
assertUnassigned(allocationService, shuffledList("throttle-low", "yes-high", "yes"));
1192-
assertAssignedTo(allocationService, "yes-low", shuffledList("yes-low", "throttle", "throttle-high"));
1186+
assertUnassigned(allocationDeciders, balancingWeightsFactory, shuffledList("throttle-low", "yes-high", "yes"));
1187+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "yes-low", shuffledList("yes-low", "throttle", "throttle-high"));
11931188
// prioritize YES over THROTTLE when weights equal
1194-
assertAssignedTo(allocationService, "yes-low", shuffledList("yes-low", "throttle-low"));
1189+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "yes-low", shuffledList("yes-low", "throttle-low"));
11951190
// prioritize YES by weight
1196-
assertAssignedTo(allocationService, "yes-low", shuffledList("yes-low", "yes", "yes-high"));
1191+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, "yes-low", shuffledList("yes-low", "yes", "yes-high"));
11971192
// prioritize NOT_PREFERRED by weight
1198-
assertAssignedTo(allocationService, "not-preferred-low", shuffledList("not-preferred-low", "not-preferred", "not-preferred-high"));
1193+
assertAssignedTo(
1194+
allocationDeciders,
1195+
balancingWeightsFactory,
1196+
"not-preferred-low",
1197+
shuffledList("not-preferred-low", "not-preferred", "not-preferred-high")
1198+
);
11991199
}
12001200

1201-
private void assertUnassigned(AllocationService allocationService, List<String> allNodeIds) {
1202-
assertAssignedTo(allocationService, null, allNodeIds);
1201+
private void assertUnassigned(
1202+
AllocationDeciders allocationDeciders,
1203+
BalancingWeightsFactory balancingWeightsFactory,
1204+
List<String> allNodeIds
1205+
) {
1206+
assertAssignedTo(allocationDeciders, balancingWeightsFactory, null, allNodeIds);
12031207
}
12041208

1205-
private void assertAssignedTo(AllocationService allocationService, @Nullable String expectedNodeId, List<String> allNodeIds) {
1209+
private void assertAssignedTo(
1210+
AllocationDeciders allocationDeciders,
1211+
BalancingWeightsFactory balancingWeightsFactory,
1212+
@Nullable String expectedNodeId,
1213+
List<String> allNodeIds
1214+
) {
12061215
final var discoveryNodesBuilder = DiscoveryNodes.builder();
12071216
for (String nodeName : allNodeIds) {
12081217
discoveryNodesBuilder.add(newNode(nodeName));
@@ -1220,13 +1229,41 @@ private void assertAssignedTo(AllocationService allocationService, @Nullable Str
12201229
.putRoutingTable(ProjectId.DEFAULT, routingTableBuilder.build())
12211230
.build();
12221231

1223-
clusterState = startInitializingShardsAndReroute(allocationService, clusterState);
1232+
clusterState = runAssignment(allocationDeciders, balancingWeightsFactory, clusterState);
12241233

12251234
final RoutingTable routingTable = clusterState.routingTable(ProjectId.DEFAULT);
12261235
final ShardRouting primaryShard = routingTable.shardRoutingTable(indexMetadata.getIndex().getName(), 0).primaryShard();
12271236
assertThat(primaryShard.currentNodeId(), equalTo(expectedNodeId));
12281237
}
12291238

1239+
private ClusterState runAssignment(
1240+
AllocationDeciders allocationDeciders,
1241+
BalancingWeightsFactory balancingWeightsFactory,
1242+
ClusterState clusterState
1243+
) {
1244+
final var routingAllocation = new RoutingAllocation(
1245+
allocationDeciders,
1246+
clusterState.getRoutingNodes().mutableCopy(),
1247+
clusterState,
1248+
ClusterInfo.EMPTY,
1249+
SnapshotShardSizeInfo.EMPTY,
1250+
System.nanoTime()
1251+
);
1252+
1253+
// Debug mode should not change the outcome
1254+
routingAllocation.setDebugMode(randomFrom(RoutingAllocation.DebugMode.values()));
1255+
1256+
final var balancedShardsAllocator = new BalancedShardsAllocator(
1257+
BalancerSettings.DEFAULT,
1258+
TEST_WRITE_LOAD_FORECASTER,
1259+
balancingWeightsFactory
1260+
);
1261+
balancedShardsAllocator.allocate(routingAllocation);
1262+
return ClusterState.builder(clusterState)
1263+
.routingTable(clusterState.globalRoutingTable().rebuild(routingAllocation.routingNodes(), clusterState.metadata()))
1264+
.build();
1265+
}
1266+
12301267
/**
12311268
* Returns specific values for {@link WeightFunction#calculateNodeWeightWithIndex} depending on the
12321269
* suffix of the node name.

0 commit comments

Comments
 (0)