Search in sources :

Example 6 with ShardRoutingState

use of org.elasticsearch.cluster.routing.ShardRoutingState in project elasticsearch by elastic.

the class ClusterAllocationExplainIT method testRebalancingNotAllowed.

public void testRebalancingNotAllowed() throws Exception {
    logger.info("--> starting a single node");
    internalCluster().startNode();
    ensureStableCluster(1);
    logger.info("--> creating an index with 5 shards, all allocated to the single node");
    createIndexAndIndexData(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());
    }
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) ClusterInfo(org.elasticsearch.cluster.ClusterInfo) UnassignedInfo(org.elasticsearch.cluster.routing.UnassignedInfo) MoveDecision(org.elasticsearch.cluster.routing.allocation.MoveDecision) AllocateUnassignedDecision(org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState) MoveDecision(org.elasticsearch.cluster.routing.allocation.MoveDecision) AllocationDecision(org.elasticsearch.cluster.routing.allocation.AllocationDecision) AllocateUnassignedDecision(org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision) Decision(org.elasticsearch.cluster.routing.allocation.decider.Decision) NodeAllocationResult(org.elasticsearch.cluster.routing.allocation.NodeAllocationResult) XContentParser(org.elasticsearch.common.xcontent.XContentParser)

Example 7 with ShardRoutingState

use of org.elasticsearch.cluster.routing.ShardRoutingState in project elasticsearch by elastic.

the class ClusterAllocationExplainIT method testAllocationFilteringPreventsShardMove.

public void testAllocationFilteringPreventsShardMove() throws Exception {
    logger.info("--> starting 2 nodes");
    internalCluster().startNodes(2);
    logger.info("--> creating an index with 1 primary and 0 replicas");
    createIndexAndIndexData(1, 0);
    logger.info("--> setting up allocation filtering to prevent allocation to both nodes");
    client().admin().indices().prepareUpdateSettings("idx").setSettings(Settings.builder().put("index.routing.allocation.include._name", "non_existent_node")).get();
    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 move shard to another node, even though it is not allowed to remain on its current node", moveDecision.getExplanation());
    assertFalse(moveDecision.canRemain());
    assertFalse(moveDecision.forceMove());
    assertFalse(moveDecision.canRebalanceCluster());
    assertNull(moveDecision.getClusterRebalanceDecision());
    assertNull(moveDecision.getTargetNode());
    assertEquals(0, moveDecision.getCurrentNodeRanking());
    // verifying can remain decision object
    assertNotNull(moveDecision.getCanRemainDecision());
    assertEquals(Decision.Type.NO, moveDecision.getCanRemainDecision().type());
    for (Decision d : moveDecision.getCanRemainDecision().getDecisions()) {
        if (d.label().equals("filter")) {
            assertEquals(Decision.Type.NO, d.type());
            assertEquals("node does not match index setting [index.routing.allocation.include] filters [_name:\"non_existent_node\"]", 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.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.label().equals("filter")) {
            assertEquals(Decision.Type.NO, d.type());
            assertEquals("node does not match index setting [index.routing.allocation.include] filters [_name:\"non_existent_node\"]", d.getExplanation());
        } else {
            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.NO.toString(), parser.text());
        parser.nextToken();
        assertEquals("can_remain_decisions", parser.currentName());
        verifyDeciders(parser, AllocationDecision.NO);
        parser.nextToken();
        assertEquals("can_move_to_other_node", parser.currentName());
        parser.nextToken();
        assertEquals(AllocationDecision.NO.toString(), parser.text());
        parser.nextToken();
        assertEquals("move_explanation", parser.currentName());
        parser.nextToken();
        assertEquals("cannot move shard to another node, even though it is not allowed to remain on its current node", parser.text());
        verifyNodeDecisions(parser, allNodeDecisions(AllocationDecision.NO, true), includeYesDecisions, false);
        assertEquals(Token.END_OBJECT, parser.nextToken());
    }
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) ClusterInfo(org.elasticsearch.cluster.ClusterInfo) UnassignedInfo(org.elasticsearch.cluster.routing.UnassignedInfo) MoveDecision(org.elasticsearch.cluster.routing.allocation.MoveDecision) AllocateUnassignedDecision(org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState) MoveDecision(org.elasticsearch.cluster.routing.allocation.MoveDecision) AllocationDecision(org.elasticsearch.cluster.routing.allocation.AllocationDecision) AllocateUnassignedDecision(org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision) Decision(org.elasticsearch.cluster.routing.allocation.decider.Decision) NodeAllocationResult(org.elasticsearch.cluster.routing.allocation.NodeAllocationResult) XContentParser(org.elasticsearch.common.xcontent.XContentParser)

Example 8 with ShardRoutingState

use of org.elasticsearch.cluster.routing.ShardRoutingState in project elasticsearch by elastic.

the class ClusterStateCreationUtils method state.

/**
     * Creates cluster state with and index that has one shard and #(replicaStates) replicas
     *
     * @param index              name of the index
     * @param activePrimaryLocal if active primary should coincide with the local node in the cluster state
     * @param primaryState       state of primary
     * @param replicaStates      states of the replicas. length of this array determines also the number of replicas
     */
public static ClusterState state(String index, boolean activePrimaryLocal, ShardRoutingState primaryState, ShardRoutingState... replicaStates) {
    final int numberOfReplicas = replicaStates.length;
    int numberOfNodes = numberOfReplicas + 1;
    if (primaryState == ShardRoutingState.RELOCATING) {
        numberOfNodes++;
    }
    for (ShardRoutingState state : replicaStates) {
        if (state == ShardRoutingState.RELOCATING) {
            numberOfNodes++;
        }
    }
    // we need a non-local master to test shard failures
    numberOfNodes = Math.max(2, numberOfNodes);
    final ShardId shardId = new ShardId(index, "_na_", 0);
    DiscoveryNodes.Builder discoBuilder = DiscoveryNodes.builder();
    Set<String> unassignedNodes = new HashSet<>();
    for (int i = 0; i < numberOfNodes + 1; i++) {
        final DiscoveryNode node = newNode(i);
        discoBuilder = discoBuilder.add(node);
        unassignedNodes.add(node.getId());
    }
    discoBuilder.localNodeId(newNode(0).getId());
    // we need a non-local master to test shard failures
    discoBuilder.masterNodeId(newNode(1).getId());
    final int primaryTerm = 1 + randomInt(200);
    IndexMetaData indexMetaData = IndexMetaData.builder(index).settings(Settings.builder().put(SETTING_VERSION_CREATED, Version.CURRENT).put(SETTING_NUMBER_OF_SHARDS, 1).put(SETTING_NUMBER_OF_REPLICAS, numberOfReplicas).put(SETTING_CREATION_DATE, System.currentTimeMillis())).primaryTerm(0, primaryTerm).build();
    RoutingTable.Builder routing = new RoutingTable.Builder();
    routing.addAsNew(indexMetaData);
    IndexShardRoutingTable.Builder indexShardRoutingBuilder = new IndexShardRoutingTable.Builder(shardId);
    String primaryNode = null;
    String relocatingNode = null;
    UnassignedInfo unassignedInfo = null;
    if (primaryState != ShardRoutingState.UNASSIGNED) {
        if (activePrimaryLocal) {
            primaryNode = newNode(0).getId();
            unassignedNodes.remove(primaryNode);
        } else {
            Set<String> unassignedNodesExecludingPrimary = new HashSet<>(unassignedNodes);
            unassignedNodesExecludingPrimary.remove(newNode(0).getId());
            primaryNode = selectAndRemove(unassignedNodesExecludingPrimary);
            unassignedNodes.remove(primaryNode);
        }
        if (primaryState == ShardRoutingState.RELOCATING) {
            relocatingNode = selectAndRemove(unassignedNodes);
        }
    } else {
        unassignedInfo = new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, null);
    }
    indexShardRoutingBuilder.addShard(TestShardRouting.newShardRouting(index, 0, primaryNode, relocatingNode, true, primaryState, unassignedInfo));
    for (ShardRoutingState replicaState : replicaStates) {
        String replicaNode = null;
        relocatingNode = null;
        unassignedInfo = null;
        if (replicaState != ShardRoutingState.UNASSIGNED) {
            assert primaryNode != null : "a replica is assigned but the primary isn't";
            replicaNode = selectAndRemove(unassignedNodes);
            if (replicaState == ShardRoutingState.RELOCATING) {
                relocatingNode = selectAndRemove(unassignedNodes);
            }
        } else {
            unassignedInfo = new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, null);
        }
        indexShardRoutingBuilder.addShard(TestShardRouting.newShardRouting(index, shardId.id(), replicaNode, relocatingNode, false, replicaState, unassignedInfo));
    }
    ClusterState.Builder state = ClusterState.builder(new ClusterName("test"));
    state.nodes(discoBuilder);
    state.metaData(MetaData.builder().put(indexMetaData, false).generateClusterUuidIfNeeded());
    state.routingTable(RoutingTable.builder().add(IndexRoutingTable.builder(indexMetaData.getIndex()).addIndexShard(indexShardRoutingBuilder.build())).build());
    return state.build();
}
Also used : IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) ClusterState(org.elasticsearch.cluster.ClusterState) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) UnassignedInfo(org.elasticsearch.cluster.routing.UnassignedInfo) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) ShardId(org.elasticsearch.index.shard.ShardId) IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.elasticsearch.cluster.routing.IndexRoutingTable) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) ClusterName(org.elasticsearch.cluster.ClusterName) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes) HashSet(java.util.HashSet)

Example 9 with ShardRoutingState

use of org.elasticsearch.cluster.routing.ShardRoutingState in project elasticsearch by elastic.

the class ReplicationOperationTests method testWaitForActiveShards.

public void testWaitForActiveShards() throws Exception {
    final String index = "test";
    final ShardId shardId = new ShardId(index, "_na_", 0);
    final int assignedReplicas = randomInt(2);
    final int unassignedReplicas = randomInt(2);
    final int totalShards = 1 + assignedReplicas + unassignedReplicas;
    final int activeShardCount = randomIntBetween(0, totalShards);
    Request request = new Request(shardId).waitForActiveShards(activeShardCount == totalShards ? ActiveShardCount.ALL : ActiveShardCount.from(activeShardCount));
    final boolean passesActiveShardCheck = activeShardCount <= assignedReplicas + 1;
    ShardRoutingState[] replicaStates = new ShardRoutingState[assignedReplicas + unassignedReplicas];
    for (int i = 0; i < assignedReplicas; i++) {
        replicaStates[i] = randomFrom(ShardRoutingState.STARTED, ShardRoutingState.RELOCATING);
    }
    for (int i = assignedReplicas; i < replicaStates.length; i++) {
        replicaStates[i] = ShardRoutingState.UNASSIGNED;
    }
    final ClusterState state = state(index, true, ShardRoutingState.STARTED, replicaStates);
    logger.debug("using active shard count of [{}], assigned shards [{}], total shards [{}]." + " expecting op to [{}]. using state: \n{}", request.waitForActiveShards(), 1 + assignedReplicas, 1 + assignedReplicas + unassignedReplicas, passesActiveShardCheck ? "succeed" : "retry", state);
    final long primaryTerm = state.metaData().index(index).primaryTerm(shardId.id());
    final IndexShardRoutingTable shardRoutingTable = state.routingTable().index(index).shard(shardId.id());
    PlainActionFuture<TestPrimary.Result> listener = new PlainActionFuture<>();
    final ShardRouting primaryShard = shardRoutingTable.primaryShard();
    final TestReplicationOperation op = new TestReplicationOperation(request, new TestPrimary(primaryShard, primaryTerm), listener, randomBoolean(), new TestReplicaProxy(), () -> state, logger, "test");
    if (passesActiveShardCheck) {
        assertThat(op.checkActiveShardCount(), nullValue());
        op.execute();
        assertTrue("operations should have been performed, active shard count is met", request.processedOnPrimary.get());
    } else {
        assertThat(op.checkActiveShardCount(), notNullValue());
        op.execute();
        assertFalse("operations should not have been perform, active shard count is *NOT* met", request.processedOnPrimary.get());
        assertListenerThrows("should throw exception to trigger retry", listener, UnavailableShardsException.class);
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState) ShardId(org.elasticsearch.index.shard.ShardId) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 10 with ShardRoutingState

use of org.elasticsearch.cluster.routing.ShardRoutingState in project elasticsearch by elastic.

the class IndicesStoreTests method testShardCanBeDeletedNoShardStarted.

public void testShardCanBeDeletedNoShardStarted() throws Exception {
    int numShards = randomIntBetween(1, 7);
    int numReplicas = randomInt(2);
    IndexShardRoutingTable.Builder routingTable = new IndexShardRoutingTable.Builder(new ShardId("test", "_na_", 1));
    for (int i = 0; i < numShards; i++) {
        int unStartedShard = randomInt(numReplicas);
        for (int j = 0; j <= numReplicas; j++) {
            ShardRoutingState state;
            if (j == unStartedShard) {
                state = randomFrom(NOT_STARTED_STATES);
            } else {
                state = randomFrom(ShardRoutingState.values());
            }
            UnassignedInfo unassignedInfo = null;
            if (state == ShardRoutingState.UNASSIGNED) {
                unassignedInfo = new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, null);
            }
            String relocatingNodeId = state == ShardRoutingState.RELOCATING ? randomAsciiOfLength(10) : null;
            routingTable.addShard(TestShardRouting.newShardRouting("test", i, randomAsciiOfLength(10), relocatingNodeId, j == 0, state, unassignedInfo));
        }
    }
    assertFalse(IndicesStore.shardCanBeDeleted(localNode.getId(), routingTable.build()));
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) UnassignedInfo(org.elasticsearch.cluster.routing.UnassignedInfo) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState)

Aggregations

ShardRoutingState (org.elasticsearch.cluster.routing.ShardRoutingState)17 ShardId (org.elasticsearch.index.shard.ShardId)13 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)12 UnassignedInfo (org.elasticsearch.cluster.routing.UnassignedInfo)12 AllocateUnassignedDecision (org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision)10 MoveDecision (org.elasticsearch.cluster.routing.allocation.MoveDecision)10 XContentParser (org.elasticsearch.common.xcontent.XContentParser)10 ClusterInfo (org.elasticsearch.cluster.ClusterInfo)9 NodeAllocationResult (org.elasticsearch.cluster.routing.allocation.NodeAllocationResult)9 AllocationDecision (org.elasticsearch.cluster.routing.allocation.AllocationDecision)8 Decision (org.elasticsearch.cluster.routing.allocation.decider.Decision)8 ClusterState (org.elasticsearch.cluster.ClusterState)6 Matchers.containsString (org.hamcrest.Matchers.containsString)6 HashMap (java.util.HashMap)4 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)4 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)4 IndexMetaData (org.elasticsearch.cluster.metadata.IndexMetaData)3 HashSet (java.util.HashSet)2 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)2 IndexRoutingTable (org.elasticsearch.cluster.routing.IndexRoutingTable)2