use of org.opensearch.cluster.routing.UnassignedInfo in project OpenSearch by opensearch-project.
the class ClusterAllocationExplainIT method testAssignedReplicaOnSpecificNode.
public void testAssignedReplicaOnSpecificNode() throws Exception {
logger.info("--> starting 3 nodes");
List<String> nodes = internalCluster().startNodes(3);
String excludedNode = nodes.get(randomIntBetween(0, 2));
prepareIndex(randomIndexState(), 1, 2, Settings.builder().put("index.routing.allocation.exclude._name", excludedNode).build(), ActiveShardCount.from(2));
boolean includeYesDecisions = randomBoolean();
boolean includeDiskInfo = randomBoolean();
ClusterAllocationExplanation explanation = runExplain(false, replicaNode().getId(), includeYesDecisions, includeDiskInfo);
ShardId shardId = explanation.getShard();
boolean isPrimary = explanation.isPrimary();
ShardRoutingState shardRoutingState = explanation.getShardState();
DiscoveryNode currentNode = explanation.getCurrentNode();
UnassignedInfo unassignedInfo = explanation.getUnassignedInfo();
ClusterInfo clusterInfo = explanation.getClusterInfo();
AllocateUnassignedDecision allocateDecision = explanation.getShardAllocationDecision().getAllocateDecision();
MoveDecision moveDecision = explanation.getShardAllocationDecision().getMoveDecision();
// verify shard info
assertEquals("idx", shardId.getIndexName());
assertEquals(0, shardId.getId());
assertFalse(isPrimary);
// verify current node info
assertEquals(ShardRoutingState.STARTED, shardRoutingState);
assertNotNull(currentNode);
assertEquals(replicaNode().getName(), currentNode.getName());
// verify unassigned info
assertNull(unassignedInfo);
// verify cluster info
verifyClusterInfo(clusterInfo, includeDiskInfo, 3);
// verify decision objects
assertFalse(allocateDecision.isDecisionTaken());
assertTrue(moveDecision.isDecisionTaken());
assertEquals(AllocationDecision.NO, moveDecision.getAllocationDecision());
assertEquals("rebalancing is not allowed", moveDecision.getExplanation());
assertTrue(moveDecision.canRemain());
assertFalse(moveDecision.forceMove());
assertFalse(moveDecision.canRebalanceCluster());
assertNotNull(moveDecision.getCanRemainDecision());
assertNull(moveDecision.getTargetNode());
// verifying cluster rebalance decision object
assertNotNull(moveDecision.getClusterRebalanceDecision());
assertEquals(Decision.Type.NO, moveDecision.getClusterRebalanceDecision().type());
// verify node decisions
assertEquals(2, moveDecision.getNodeDecisions().size());
for (NodeAllocationResult result : moveDecision.getNodeDecisions()) {
assertNotNull(result.getNode());
assertEquals(1, result.getWeightRanking());
assertEquals(AllocationDecision.NO, result.getNodeDecision());
if (includeYesDecisions) {
assertThat(result.getCanAllocateDecision().getDecisions().size(), greaterThan(1));
} else {
assertEquals(1, result.getCanAllocateDecision().getDecisions().size());
}
for (Decision d : result.getCanAllocateDecision().getDecisions()) {
if (d.type() == Decision.Type.NO) {
assertThat(d.label(), is(oneOf("filter", "same_shard")));
}
assertNotNull(d.getExplanation());
}
}
// verify JSON output
try (XContentParser parser = getParser(explanation)) {
verifyShardInfo(parser, false, includeDiskInfo, ShardRoutingState.STARTED);
parser.nextToken();
assertEquals("can_remain_on_current_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.YES.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_cluster", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_cluster_decisions", parser.currentName());
verifyDeciders(parser, AllocationDecision.NO);
parser.nextToken();
assertEquals("can_rebalance_to_other_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("rebalance_explanation", parser.currentName());
parser.nextToken();
assertEquals("rebalancing is not allowed", parser.text());
verifyNodeDecisions(parser, allNodeDecisions(AllocationDecision.NO, false), includeYesDecisions, false);
assertEquals(Token.END_OBJECT, parser.nextToken());
}
}
use of org.opensearch.cluster.routing.UnassignedInfo in project OpenSearch by opensearch-project.
the class ClusterAllocationExplainIT method testCannotAllocateStaleReplicaExplanation.
public void testCannotAllocateStaleReplicaExplanation() throws Exception {
logger.info("--> starting 3 nodes");
final String masterNode = internalCluster().startNode();
// start replica node first, so it's path will be used first when we start a node after
// stopping all of them at end of test.
final String replicaNode = internalCluster().startNode();
Settings replicaDataPathSettings = internalCluster().dataPathSettings(replicaNode);
final String primaryNode = internalCluster().startNode();
prepareIndex(IndexMetadata.State.OPEN, 1, 1, Settings.builder().put("index.routing.allocation.include._name", primaryNode).put("index.routing.allocation.exclude._name", masterNode).build(), ActiveShardCount.ONE);
client().admin().indices().prepareUpdateSettings("idx").setSettings(Settings.builder().put("index.routing.allocation.include._name", (String) null)).get();
ensureGreen();
assertThat(replicaNode().getName(), equalTo(replicaNode));
assertThat(primaryNodeName(), equalTo(primaryNode));
logger.info("--> stop node with the replica shard");
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(replicaNode));
final IndexMetadata.State indexState = randomIndexState();
if (indexState == IndexMetadata.State.OPEN) {
logger.info("--> index more data, now the replica is stale");
indexData();
} else {
logger.info("--> close the index, now the replica is stale");
assertAcked(client().admin().indices().prepareClose("idx"));
final ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth("idx").setTimeout(TimeValue.timeValueSeconds(30)).setWaitForActiveShards(ActiveShardCount.ONE).setWaitForNoInitializingShards(true).setWaitForEvents(Priority.LANGUID).get();
assertThat(clusterHealthResponse.getStatus().value(), lessThanOrEqualTo(ClusterHealthStatus.YELLOW.value()));
}
logger.info("--> stop the node with the primary");
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(primaryNode));
logger.info("--> restart the node with the stale replica");
String restartedNode = internalCluster().startDataOnlyNode(replicaDataPathSettings);
// wait for the master to finish processing join.
ensureClusterSizeConsistency();
// wait until the system has fetched shard data and we know there is no valid shard copy
assertBusy(() -> {
ClusterAllocationExplanation explanation = client().admin().cluster().prepareAllocationExplain().setIndex("idx").setShard(0).setPrimary(true).get().getExplanation();
assertTrue(explanation.getShardAllocationDecision().getAllocateDecision().isDecisionTaken());
assertEquals(AllocationDecision.NO_VALID_SHARD_COPY, explanation.getShardAllocationDecision().getAllocateDecision().getAllocationDecision());
});
boolean includeYesDecisions = randomBoolean();
boolean includeDiskInfo = randomBoolean();
ClusterAllocationExplanation explanation = runExplain(true, includeYesDecisions, includeDiskInfo);
ShardId shardId = explanation.getShard();
boolean isPrimary = explanation.isPrimary();
ShardRoutingState shardRoutingState = explanation.getShardState();
DiscoveryNode currentNode = explanation.getCurrentNode();
UnassignedInfo unassignedInfo = explanation.getUnassignedInfo();
AllocateUnassignedDecision allocateDecision = explanation.getShardAllocationDecision().getAllocateDecision();
MoveDecision moveDecision = explanation.getShardAllocationDecision().getMoveDecision();
// verify shard info
assertEquals("idx", shardId.getIndexName());
assertEquals(0, shardId.getId());
assertTrue(isPrimary);
// verify current node info
assertEquals(ShardRoutingState.UNASSIGNED, shardRoutingState);
assertNull(currentNode);
// verify unassigned info
assertNotNull(unassignedInfo);
// verify decision object
assertTrue(allocateDecision.isDecisionTaken());
assertFalse(moveDecision.isDecisionTaken());
assertEquals(AllocationDecision.NO_VALID_SHARD_COPY, allocateDecision.getAllocationDecision());
assertEquals(2, allocateDecision.getNodeDecisions().size());
for (NodeAllocationResult nodeAllocationResult : allocateDecision.getNodeDecisions()) {
if (nodeAllocationResult.getNode().getName().equals(restartedNode)) {
assertNotNull(nodeAllocationResult.getShardStoreInfo());
assertNotNull(nodeAllocationResult.getShardStoreInfo().getAllocationId());
assertFalse(nodeAllocationResult.getShardStoreInfo().isInSync());
assertNull(nodeAllocationResult.getShardStoreInfo().getStoreException());
} else {
assertNotNull(nodeAllocationResult.getShardStoreInfo());
assertNull(nodeAllocationResult.getShardStoreInfo().getAllocationId());
assertFalse(nodeAllocationResult.getShardStoreInfo().isInSync());
assertNull(nodeAllocationResult.getShardStoreInfo().getStoreException());
}
}
// verify JSON output
try (XContentParser parser = getParser(explanation)) {
verifyShardInfo(parser, true, includeDiskInfo, ShardRoutingState.UNASSIGNED);
parser.nextToken();
assertEquals("can_allocate", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO_VALID_SHARD_COPY.toString(), parser.text());
parser.nextToken();
assertEquals("allocate_explanation", parser.currentName());
parser.nextToken();
assertEquals("cannot allocate because all found copies of the shard are either stale or corrupt", parser.text());
verifyStaleShardCopyNodeDecisions(parser, 2, Collections.singleton(restartedNode));
}
}
use of org.opensearch.cluster.routing.UnassignedInfo in project OpenSearch by opensearch-project.
the class ClusterAllocationExplainIT method testRebalancingNotAllowed.
public void testRebalancingNotAllowed() throws Exception {
logger.info("--> starting a single node");
internalCluster().startNode();
ensureStableCluster(1);
prepareIndex(5, 0);
logger.info("--> disabling rebalancing on the index");
client().admin().indices().prepareUpdateSettings("idx").setSettings(Settings.builder().put("index.routing.rebalance.enable", "none")).get();
logger.info("--> starting another node, with rebalancing disabled, it should get no shards");
internalCluster().startNode();
ensureStableCluster(2);
boolean includeYesDecisions = randomBoolean();
boolean includeDiskInfo = randomBoolean();
ClusterAllocationExplanation explanation = runExplain(true, includeYesDecisions, includeDiskInfo);
ShardId shardId = explanation.getShard();
boolean isPrimary = explanation.isPrimary();
ShardRoutingState shardRoutingState = explanation.getShardState();
DiscoveryNode currentNode = explanation.getCurrentNode();
UnassignedInfo unassignedInfo = explanation.getUnassignedInfo();
ClusterInfo clusterInfo = explanation.getClusterInfo();
AllocateUnassignedDecision allocateDecision = explanation.getShardAllocationDecision().getAllocateDecision();
MoveDecision moveDecision = explanation.getShardAllocationDecision().getMoveDecision();
// verify shard info
assertEquals("idx", shardId.getIndexName());
assertEquals(0, shardId.getId());
assertTrue(isPrimary);
// verify current node info
assertEquals(ShardRoutingState.STARTED, shardRoutingState);
assertNotNull(currentNode);
// verify unassigned info
assertNull(unassignedInfo);
// verify cluster info
verifyClusterInfo(clusterInfo, includeDiskInfo, 2);
// verify decision object
assertFalse(allocateDecision.isDecisionTaken());
assertTrue(moveDecision.isDecisionTaken());
assertEquals(AllocationDecision.NO, moveDecision.getAllocationDecision());
assertEquals("rebalancing is not allowed, even though there is at least one node on which the shard can be allocated", moveDecision.getExplanation());
assertTrue(moveDecision.canRemain());
assertFalse(moveDecision.forceMove());
assertFalse(moveDecision.canRebalanceCluster());
assertNotNull(moveDecision.getCanRemainDecision());
assertNull(moveDecision.getTargetNode());
assertEquals(2, moveDecision.getCurrentNodeRanking());
// verifying cluster rebalance decision object
assertNotNull(moveDecision.getClusterRebalanceDecision());
assertEquals(Decision.Type.NO, moveDecision.getClusterRebalanceDecision().type());
for (Decision d : moveDecision.getClusterRebalanceDecision().getDecisions()) {
if (d.label().equals("enable")) {
assertEquals(Decision.Type.NO, d.type());
assertEquals("no rebalancing is allowed due to index setting [index.routing.rebalance.enable=none]", d.getExplanation());
} else {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
}
// verify node decisions
assertEquals(1, moveDecision.getNodeDecisions().size());
NodeAllocationResult result = moveDecision.getNodeDecisions().get(0);
assertNotNull(result.getNode());
assertEquals(1, result.getWeightRanking());
assertEquals(AllocationDecision.YES, result.getNodeDecision());
if (includeYesDecisions) {
assertThat(result.getCanAllocateDecision().getDecisions().size(), greaterThan(0));
} else {
assertEquals(0, result.getCanAllocateDecision().getDecisions().size());
}
for (Decision d : result.getCanAllocateDecision().getDecisions()) {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
// verify JSON output
try (XContentParser parser = getParser(explanation)) {
verifyShardInfo(parser, true, includeDiskInfo, ShardRoutingState.STARTED);
parser.nextToken();
assertEquals("can_remain_on_current_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.YES.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_cluster", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_cluster_decisions", parser.currentName());
verifyDeciders(parser, AllocationDecision.NO);
parser.nextToken();
assertEquals("can_rebalance_to_other_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("rebalance_explanation", parser.currentName());
parser.nextToken();
assertEquals("rebalancing is not allowed, even though there is at least one node on which the shard can be allocated", parser.text());
verifyNodeDecisions(parser, allNodeDecisions(AllocationDecision.YES, true), includeYesDecisions, false);
assertEquals(Token.END_OBJECT, parser.nextToken());
}
}
use of org.opensearch.cluster.routing.UnassignedInfo in project OpenSearch by opensearch-project.
the class ClusterAllocationExplainIT method testWorseBalance.
public void testWorseBalance() throws Exception {
logger.info("--> starting a single node");
internalCluster().startNode();
ensureStableCluster(1);
prepareIndex(5, 0);
logger.info("--> setting balancing threshold really high, so it won't be met");
client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put("cluster.routing.allocation.balance.threshold", 1000.0f)).get();
logger.info("--> starting another node, with the rebalance threshold so high, it should not get any shards");
internalCluster().startNode();
ensureStableCluster(2);
boolean includeYesDecisions = randomBoolean();
boolean includeDiskInfo = randomBoolean();
ClusterAllocationExplanation explanation = runExplain(true, includeYesDecisions, includeDiskInfo);
ShardId shardId = explanation.getShard();
boolean isPrimary = explanation.isPrimary();
ShardRoutingState shardRoutingState = explanation.getShardState();
DiscoveryNode currentNode = explanation.getCurrentNode();
UnassignedInfo unassignedInfo = explanation.getUnassignedInfo();
ClusterInfo clusterInfo = explanation.getClusterInfo();
AllocateUnassignedDecision allocateDecision = explanation.getShardAllocationDecision().getAllocateDecision();
MoveDecision moveDecision = explanation.getShardAllocationDecision().getMoveDecision();
// verify shard info
assertEquals("idx", shardId.getIndexName());
assertEquals(0, shardId.getId());
assertTrue(isPrimary);
// verify current node info
assertEquals(ShardRoutingState.STARTED, shardRoutingState);
assertNotNull(currentNode);
// verify unassigned info
assertNull(unassignedInfo);
// verify cluster info
verifyClusterInfo(clusterInfo, includeDiskInfo, 2);
// verify decision object
assertFalse(allocateDecision.isDecisionTaken());
assertTrue(moveDecision.isDecisionTaken());
assertEquals(AllocationDecision.NO, moveDecision.getAllocationDecision());
assertEquals("cannot rebalance as no target node exists that can both allocate this shard and improve the cluster balance", moveDecision.getExplanation());
assertTrue(moveDecision.canRemain());
assertFalse(moveDecision.forceMove());
assertTrue(moveDecision.canRebalanceCluster());
assertNotNull(moveDecision.getCanRemainDecision());
assertNull(moveDecision.getTargetNode());
assertEquals(1, moveDecision.getCurrentNodeRanking());
// verifying cluster rebalance decision object
assertNotNull(moveDecision.getClusterRebalanceDecision());
assertEquals(Decision.Type.YES, moveDecision.getClusterRebalanceDecision().type());
for (Decision d : moveDecision.getClusterRebalanceDecision().getDecisions()) {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
// verify node decisions
assertEquals(1, moveDecision.getNodeDecisions().size());
NodeAllocationResult result = moveDecision.getNodeDecisions().get(0);
assertNotNull(result.getNode());
assertEquals(1, result.getWeightRanking());
assertEquals(AllocationDecision.WORSE_BALANCE, result.getNodeDecision());
if (includeYesDecisions) {
assertThat(result.getCanAllocateDecision().getDecisions().size(), greaterThan(0));
} else {
assertEquals(0, result.getCanAllocateDecision().getDecisions().size());
}
for (Decision d : result.getCanAllocateDecision().getDecisions()) {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
// verify JSON output
try (XContentParser parser = getParser(explanation)) {
verifyShardInfo(parser, true, includeDiskInfo, ShardRoutingState.STARTED);
parser.nextToken();
assertEquals("can_remain_on_current_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.YES.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_cluster", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.YES.toString(), parser.text());
parser.nextToken();
assertEquals("can_rebalance_to_other_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("rebalance_explanation", parser.currentName());
parser.nextToken();
assertEquals("cannot rebalance as no target node exists that can both allocate this shard and improve the cluster balance", parser.text());
verifyNodeDecisions(parser, allNodeDecisions(AllocationDecision.WORSE_BALANCE, true), includeYesDecisions, false);
assertEquals(Token.END_OBJECT, parser.nextToken());
}
}
use of org.opensearch.cluster.routing.UnassignedInfo in project OpenSearch by opensearch-project.
the class SharedClusterSnapshotRestoreIT method testUnrestorableFilesDuringRestore.
/**
* Test that restoring a snapshot whose files can't be downloaded at all is not stuck or
* does not hang indefinitely.
*/
public void testUnrestorableFilesDuringRestore() throws Exception {
final String indexName = "unrestorable-files";
final int maxRetries = randomIntBetween(1, 10);
Settings createIndexSettings = Settings.builder().put(SETTING_ALLOCATION_MAX_RETRY.getKey(), maxRetries).put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1).build();
Settings repositorySettings = Settings.builder().put("random", randomAlphaOfLength(10)).put("max_failure_number", 10000000L).put("use_lucene_corruption", false).put("random_data_file_io_exception_rate", 1.0).build();
Consumer<UnassignedInfo> checkUnassignedInfo = unassignedInfo -> {
assertThat(unassignedInfo.getReason(), equalTo(UnassignedInfo.Reason.ALLOCATION_FAILED));
assertThat(unassignedInfo.getNumFailedAllocations(), anyOf(equalTo(maxRetries), equalTo(1)));
};
unrestorableUseCase(indexName, createIndexSettings, repositorySettings, Settings.EMPTY, checkUnassignedInfo, () -> {
});
}
Aggregations