Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer primaries in cluster allocation explain #76220

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,14 @@ public static ClusterAllocationExplanation explainShard(
public static ShardRouting findShardToExplain(ClusterAllocationExplainRequest request, RoutingAllocation allocation) {
ShardRouting foundShard = null;
if (request.useAnyUnassignedShard()) {
// If we can use any shard, just pick the first unassigned one (if there are any)
RoutingNodes.UnassignedShards.UnassignedIterator ui = allocation.routingNodes().unassigned().iterator();
if (ui.hasNext()) {
foundShard = ui.next();
// If we can use any shard, return the first unassigned primary (if there is one) or the first unassigned replica (if not)
for (ShardRouting unassigned : allocation.routingNodes().unassigned()) {
if (foundShard == null || unassigned.primary()) {
foundShard = unassigned;
}
if (foundShard.primary()) {
break;
}
}
if (foundShard == null) {
throw new IllegalArgumentException("No shard was specified in the request which means the response should explain a " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

import org.elasticsearch.action.support.replication.ClusterStateCreationUtils;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
import org.elasticsearch.cluster.routing.RoutingNode;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.ShardRoutingState;
import org.elasticsearch.cluster.routing.UnassignedInfo;
Expand Down Expand Up @@ -114,6 +117,33 @@ public void testFindAnyUnassignedShardToExplain() {
shard = findShardToExplain(request, routingAllocation(clusterState));
assertEquals(clusterState.getRoutingTable().index("idx").shard(0).replicaShards().get(0), shard);

// prefer unassigned primary to replica
clusterState = ClusterStateCreationUtils.stateWithAssignedPrimariesAndReplicas(new String[]{"idx1", "idx2"}, 1, 1);
final String redIndex = randomBoolean() ? "idx1" : "idx2";
final RoutingTable.Builder routingTableBuilder = RoutingTable.builder(clusterState.routingTable());
for (final IndexRoutingTable indexRoutingTable : clusterState.routingTable()) {
final IndexRoutingTable.Builder indexBuilder = new IndexRoutingTable.Builder(indexRoutingTable.getIndex());
for (final IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) {
final IndexShardRoutingTable.Builder shardBuilder = new IndexShardRoutingTable.Builder(indexShardRoutingTable.shardId());
for (final ShardRouting shardRouting : indexShardRoutingTable) {
if (shardRouting.primary() == false || indexRoutingTable.getIndex().getName().equals(redIndex)) {
// move all replicas and one primary to unassigned
shardBuilder.addShard(shardRouting.moveToUnassigned(new UnassignedInfo(
UnassignedInfo.Reason.ALLOCATION_FAILED,
"test")));
} else {
shardBuilder.addShard(shardRouting);
}
}
indexBuilder.addIndexShard(shardBuilder.build());
}
routingTableBuilder.add(indexBuilder);
}
clusterState = ClusterState.builder(clusterState).routingTable(routingTableBuilder.build()).build();
request = new ClusterAllocationExplainRequest();
shard = findShardToExplain(request, routingAllocation(clusterState));
assertEquals(clusterState.getRoutingTable().index(redIndex).shard(0).primaryShard(), shard);

// no unassigned shard to explain
final ClusterState allStartedClusterState = ClusterStateCreationUtils.state("idx", randomBoolean(),
ShardRoutingState.STARTED, ShardRoutingState.STARTED);
Expand Down