Skip to content

Commit 2295411

Browse files
authored
Fix updateMinNode condition (#80403)
Today the `BalancedShardsAllocator` doesn't correctly compute the best rebalance operation when running in `explain` mode. This commit addresses that. Closes #41194
1 parent 29e02f8 commit 2295411

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ private AllocateUnassignedDecision decideAllocateUnassigned(final ShardRouting s
10131013
updateMinNode = currentDecision.type() == Type.YES;
10141014
}
10151015
} else {
1016-
updateMinNode = true;
1016+
updateMinNode = currentWeight < minWeight;
10171017
}
10181018
if (updateMinNode) {
10191019
minNode = node;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.cluster.routing.allocation.allocator;
10+
11+
import org.elasticsearch.Version;
12+
import org.elasticsearch.action.support.replication.ClusterStateCreationUtils;
13+
import org.elasticsearch.cluster.ClusterInfo;
14+
import org.elasticsearch.cluster.ClusterState;
15+
import org.elasticsearch.cluster.ESAllocationTestCase;
16+
import org.elasticsearch.cluster.metadata.IndexMetadata;
17+
import org.elasticsearch.cluster.metadata.Metadata;
18+
import org.elasticsearch.cluster.routing.RoutingNodes;
19+
import org.elasticsearch.cluster.routing.RoutingTable;
20+
import org.elasticsearch.cluster.routing.ShardRouting;
21+
import org.elasticsearch.cluster.routing.ShardRoutingState;
22+
import org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision;
23+
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
24+
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
25+
import org.elasticsearch.common.settings.Settings;
26+
import org.elasticsearch.snapshots.SnapshotShardSizeInfo;
27+
28+
import java.util.Collections;
29+
import java.util.List;
30+
31+
public class BalancedShardsAllocatorTests extends ESAllocationTestCase {
32+
33+
public void testDecideShardAllocation() {
34+
BalancedShardsAllocator allocator = new BalancedShardsAllocator(Settings.EMPTY);
35+
ClusterState clusterState = ClusterStateCreationUtils.state("idx", false, ShardRoutingState.STARTED);
36+
assertEquals(clusterState.nodes().getSize(), 3);
37+
38+
// add new index
39+
String index = "idx_new";
40+
Metadata metadata = Metadata.builder(clusterState.metadata())
41+
.put(IndexMetadata.builder(index).settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(0))
42+
.build();
43+
RoutingTable initialRoutingTable = RoutingTable.builder(clusterState.routingTable()).addAsNew(metadata.index(index)).build();
44+
clusterState = ClusterState.builder(clusterState).metadata(metadata).routingTable(initialRoutingTable).build();
45+
46+
ShardRouting shard = clusterState.routingTable().index("idx_new").shard(0).primaryShard();
47+
RoutingAllocation allocation = new RoutingAllocation(
48+
new AllocationDeciders(Collections.emptyList()),
49+
new RoutingNodes(clusterState, false),
50+
clusterState,
51+
ClusterInfo.EMPTY,
52+
SnapshotShardSizeInfo.EMPTY,
53+
System.nanoTime()
54+
);
55+
56+
allocation.debugDecision(false);
57+
AllocateUnassignedDecision allocateDecision = allocator.decideShardAllocation(shard, allocation).getAllocateDecision();
58+
allocation.debugDecision(true);
59+
AllocateUnassignedDecision allocateDecisionWithExplain = allocator.decideShardAllocation(shard, allocation).getAllocateDecision();
60+
// the allocation decision should have same target node no matter the debug is on or off
61+
assertEquals(allocateDecision.getTargetNode().getId(), allocateDecisionWithExplain.getTargetNode().getId());
62+
63+
allocator.allocate(allocation);
64+
List<ShardRouting> assignedShards = allocation.routingNodes().assignedShards(shard.shardId());
65+
assertEquals(1, assignedShards.size());
66+
// the allocation result be consistent with allocation decision
67+
assertNotNull(allocateDecision.getTargetNode().getId(), assignedShards.get(0).currentNodeId());
68+
}
69+
70+
}

0 commit comments

Comments
 (0)