Search in sources :

Example 1 with ClusterRerouteResponse

use of org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse in project OpenSearch by opensearch-project.

the class ShrinkIndexIT method testCreateShrinkIndexFails.

/**
 * Tests that we can manually recover from a failed allocation due to shards being moved away etc.
 */
public void testCreateShrinkIndexFails() throws Exception {
    internalCluster().ensureAtLeastNumDataNodes(2);
    prepareCreate("source").setSettings(Settings.builder().put(indexSettings()).put("number_of_shards", randomIntBetween(2, 7)).put("number_of_replicas", 0)).get();
    for (int i = 0; i < 20; i++) {
        client().prepareIndex("source").setSource("{\"foo\" : \"bar\", \"i\" : " + i + "}", XContentType.JSON).get();
    }
    ImmutableOpenMap<String, DiscoveryNode> dataNodes = client().admin().cluster().prepareState().get().getState().nodes().getDataNodes();
    assertTrue("at least 2 nodes but was: " + dataNodes.size(), dataNodes.size() >= 2);
    DiscoveryNode[] discoveryNodes = dataNodes.values().toArray(DiscoveryNode.class);
    String spareNode = discoveryNodes[0].getName();
    String mergeNode = discoveryNodes[1].getName();
    // ensure all shards are allocated otherwise the ensure green below might not succeed since we require the merge node
    // if we change the setting too quickly we will end up with one replica unassigned which can't be assigned anymore due
    // to the require._name below.
    ensureGreen();
    // relocate all shards to one node such that we can merge it.
    client().admin().indices().prepareUpdateSettings("source").setSettings(Settings.builder().put("index.routing.allocation.require._name", mergeNode).put("index.blocks.write", true)).get();
    ensureGreen();
    // now merge source into a single shard index
    client().admin().indices().prepareResizeIndex("source", "target").setWaitForActiveShards(ActiveShardCount.NONE).setSettings(Settings.builder().put("index.routing.allocation.exclude._name", // we manually exclude the merge node to forcefully fuck it up
    mergeNode).put("index.number_of_replicas", 0).put("index.allocation.max_retries", 1).build()).get();
    client().admin().cluster().prepareHealth("target").setWaitForEvents(Priority.LANGUID).get();
    // now we move all shards away from the merge node
    client().admin().indices().prepareUpdateSettings("source").setSettings(Settings.builder().put("index.routing.allocation.require._name", spareNode).put("index.blocks.write", true)).get();
    ensureGreen("source");
    client().admin().indices().prepareUpdateSettings(// erase the forcefully fuckup!
    "target").setSettings(Settings.builder().putNull("index.routing.allocation.exclude._name")).get();
    // wait until it fails
    assertBusy(() -> {
        ClusterStateResponse clusterStateResponse = client().admin().cluster().prepareState().get();
        RoutingTable routingTables = clusterStateResponse.getState().routingTable();
        assertTrue(routingTables.index("target").shard(0).getShards().get(0).unassigned());
        assertEquals(UnassignedInfo.Reason.ALLOCATION_FAILED, routingTables.index("target").shard(0).getShards().get(0).unassignedInfo().getReason());
        assertEquals(1, routingTables.index("target").shard(0).getShards().get(0).unassignedInfo().getNumFailedAllocations());
    });
    client().admin().indices().prepareUpdateSettings(// now relocate them all to the right node
    "source").setSettings(Settings.builder().put("index.routing.allocation.require._name", mergeNode)).get();
    ensureGreen("source");
    final InternalClusterInfoService infoService = (InternalClusterInfoService) internalCluster().getInstance(ClusterInfoService.class, internalCluster().getMasterName());
    infoService.refresh();
    // kick off a retry and wait until it's done!
    ClusterRerouteResponse clusterRerouteResponse = client().admin().cluster().prepareReroute().setRetryFailed(true).get();
    long expectedShardSize = clusterRerouteResponse.getState().routingTable().index("target").shard(0).getShards().get(0).getExpectedShardSize();
    // we support the expected shard size in the allocator to sum up over the source index shards
    assertTrue("expected shard size must be set but wasn't: " + expectedShardSize, expectedShardSize > 0);
    ensureGreen();
    assertHitCount(client().prepareSearch("target").setSize(100).setQuery(new TermsQueryBuilder("foo", "bar")).get(), 20);
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) RoutingTable(org.opensearch.cluster.routing.RoutingTable) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) ClusterStateResponse(org.opensearch.action.admin.cluster.state.ClusterStateResponse) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService) TermsQueryBuilder(org.opensearch.index.query.TermsQueryBuilder) Matchers.containsString(org.hamcrest.Matchers.containsString) ClusterRerouteResponse(org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse)

Example 2 with ClusterRerouteResponse

use of org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse in project OpenSearch by opensearch-project.

the class RelocationIT method testRelocateWhileContinuouslyIndexingAndWaitingForRefresh.

public void testRelocateWhileContinuouslyIndexingAndWaitingForRefresh() throws Exception {
    logger.info("--> starting [node1] ...");
    final String node1 = internalCluster().startNode();
    logger.info("--> creating test index ...");
    prepareCreate("test", // we
    Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0).put("index.refresh_interval", -1)).get();
    logger.info("--> index 10 docs");
    for (int i = 0; i < 10; i++) {
        client().prepareIndex("test").setId(Integer.toString(i)).setSource("field", "value" + i).execute().actionGet();
    }
    logger.info("--> flush so we have an actual index");
    client().admin().indices().prepareFlush().execute().actionGet();
    logger.info("--> index more docs so we have something in the translog");
    final List<ActionFuture<IndexResponse>> pendingIndexResponses = new ArrayList<>();
    for (int i = 10; i < 20; i++) {
        pendingIndexResponses.add(client().prepareIndex("test").setId(Integer.toString(i)).setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL).setSource("field", "value" + i).execute());
    }
    logger.info("--> start another node");
    final String node2 = internalCluster().startNode();
    ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForNodes("2").execute().actionGet();
    assertThat(clusterHealthResponse.isTimedOut(), equalTo(false));
    logger.info("--> relocate the shard from node1 to node2");
    ActionFuture<ClusterRerouteResponse> relocationListener = client().admin().cluster().prepareReroute().add(new MoveAllocationCommand("test", 0, node1, node2)).execute();
    logger.info("--> index 100 docs while relocating");
    for (int i = 20; i < 120; i++) {
        pendingIndexResponses.add(client().prepareIndex("test").setId(Integer.toString(i)).setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL).setSource("field", "value" + i).execute());
    }
    relocationListener.actionGet();
    clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForNoRelocatingShards(true).setTimeout(ACCEPTABLE_RELOCATION_TIME).execute().actionGet();
    assertThat(clusterHealthResponse.isTimedOut(), equalTo(false));
    logger.info("--> verifying count");
    assertBusy(() -> {
        client().admin().indices().prepareRefresh().execute().actionGet();
        assertTrue(pendingIndexResponses.stream().allMatch(ActionFuture::isDone));
    }, 1, TimeUnit.MINUTES);
    assertThat(client().prepareSearch("test").setSize(0).execute().actionGet().getHits().getTotalHits().value, equalTo(120L));
}
Also used : ClusterHealthResponse(org.opensearch.action.admin.cluster.health.ClusterHealthResponse) ActionFuture(org.opensearch.action.ActionFuture) ArrayList(java.util.ArrayList) MoveAllocationCommand(org.opensearch.cluster.routing.allocation.command.MoveAllocationCommand) ClusterRerouteResponse(org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse)

Example 3 with ClusterRerouteResponse

use of org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse in project OpenSearch by opensearch-project.

the class ClusterRerouteIT method testRerouteExplain.

public void testRerouteExplain() {
    Settings commonSettings = Settings.builder().build();
    logger.info("--> starting a node");
    String node_1 = internalCluster().startNode(commonSettings);
    assertThat(cluster().size(), equalTo(1));
    ClusterHealthResponse healthResponse = client().admin().cluster().prepareHealth().setWaitForNodes("1").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));
    logger.info("--> create an index with 1 shard");
    createIndex("test", Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0).build());
    if (randomBoolean()) {
        assertAcked(client().admin().indices().prepareClose("test"));
    }
    ensureGreen("test");
    logger.info("--> disable allocation");
    Settings newSettings = Settings.builder().put(CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), Allocation.NONE.name()).build();
    client().admin().cluster().prepareUpdateSettings().setTransientSettings(newSettings).execute().actionGet();
    logger.info("--> starting a second node");
    String node_2 = internalCluster().startNode(commonSettings);
    assertThat(cluster().size(), equalTo(2));
    healthResponse = client().admin().cluster().prepareHealth().setWaitForNodes("2").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));
    logger.info("--> try to move the shard from node1 to node2");
    MoveAllocationCommand cmd = new MoveAllocationCommand("test", 0, node_1, node_2);
    ClusterRerouteResponse resp = client().admin().cluster().prepareReroute().add(cmd).setExplain(true).execute().actionGet();
    RoutingExplanations e = resp.getExplanations();
    assertThat(e.explanations().size(), equalTo(1));
    RerouteExplanation explanation = e.explanations().get(0);
    assertThat(explanation.command().name(), equalTo(cmd.name()));
    assertThat(((MoveAllocationCommand) explanation.command()).shardId(), equalTo(cmd.shardId()));
    assertThat(((MoveAllocationCommand) explanation.command()).fromNode(), equalTo(cmd.fromNode()));
    assertThat(((MoveAllocationCommand) explanation.command()).toNode(), equalTo(cmd.toNode()));
    assertThat(explanation.decisions().type(), equalTo(Decision.Type.YES));
}
Also used : RoutingExplanations(org.opensearch.cluster.routing.allocation.RoutingExplanations) ClusterHealthResponse(org.opensearch.action.admin.cluster.health.ClusterHealthResponse) MoveAllocationCommand(org.opensearch.cluster.routing.allocation.command.MoveAllocationCommand) Matchers.containsString(org.hamcrest.Matchers.containsString) RerouteExplanation(org.opensearch.cluster.routing.allocation.RerouteExplanation) Settings(org.opensearch.common.settings.Settings) ClusterRerouteResponse(org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse)

Example 4 with ClusterRerouteResponse

use of org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse in project OpenSearch by opensearch-project.

the class ClusterRerouteIT method testMessageLogging.

public void testMessageLogging() throws Exception {
    final Settings settings = Settings.builder().put(EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), Allocation.NONE.name()).put(EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE.name()).build();
    final String nodeName1 = internalCluster().startNode(settings);
    assertThat(cluster().size(), equalTo(1));
    ClusterHealthResponse healthResponse = client().admin().cluster().prepareHealth().setWaitForNodes("1").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));
    final String nodeName2 = internalCluster().startNode(settings);
    assertThat(cluster().size(), equalTo(2));
    healthResponse = client().admin().cluster().prepareHealth().setWaitForNodes("2").execute().actionGet();
    assertThat(healthResponse.isTimedOut(), equalTo(false));
    final String indexName = "test_index";
    client().admin().indices().prepareCreate(indexName).setWaitForActiveShards(ActiveShardCount.NONE).setSettings(Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 2).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)).execute().actionGet();
    Logger actionLogger = LogManager.getLogger(TransportClusterRerouteAction.class);
    try (MockLogAppender dryRunMockLog = MockLogAppender.createForLoggers(actionLogger)) {
        dryRunMockLog.addExpectation(new MockLogAppender.UnseenEventExpectation("no completed message logged on dry run", TransportClusterRerouteAction.class.getName(), Level.INFO, "allocated an empty primary*"));
        AllocationCommand dryRunAllocation = new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeName1, true);
        ClusterRerouteResponse dryRunResponse = client().admin().cluster().prepareReroute().setExplain(randomBoolean()).setDryRun(true).add(dryRunAllocation).execute().actionGet();
        // during a dry run, messages exist but are not logged or exposed
        assertThat(dryRunResponse.getExplanations().getYesDecisionMessages(), hasSize(1));
        assertThat(dryRunResponse.getExplanations().getYesDecisionMessages().get(0), containsString("allocated an empty primary"));
        dryRunMockLog.assertAllExpectationsMatched();
    }
    try (MockLogAppender allocateMockLog = MockLogAppender.createForLoggers(actionLogger)) {
        allocateMockLog.addExpectation(new MockLogAppender.SeenEventExpectation("message for first allocate empty primary", TransportClusterRerouteAction.class.getName(), Level.INFO, "allocated an empty primary*" + nodeName1 + "*"));
        allocateMockLog.addExpectation(new MockLogAppender.UnseenEventExpectation("no message for second allocate empty primary", TransportClusterRerouteAction.class.getName(), Level.INFO, "allocated an empty primary*" + nodeName2 + "*"));
        AllocationCommand yesDecisionAllocation = new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeName1, true);
        AllocationCommand noDecisionAllocation = new AllocateEmptyPrimaryAllocationCommand("noexist", 1, nodeName2, true);
        ClusterRerouteResponse response = client().admin().cluster().prepareReroute().setExplain(// so we get a NO decision back rather than an exception
        true).add(yesDecisionAllocation).add(noDecisionAllocation).execute().actionGet();
        assertThat(response.getExplanations().getYesDecisionMessages(), hasSize(1));
        assertThat(response.getExplanations().getYesDecisionMessages().get(0), containsString("allocated an empty primary"));
        assertThat(response.getExplanations().getYesDecisionMessages().get(0), containsString(nodeName1));
        allocateMockLog.assertAllExpectationsMatched();
    }
}
Also used : MockLogAppender(org.opensearch.test.MockLogAppender) ClusterHealthResponse(org.opensearch.action.admin.cluster.health.ClusterHealthResponse) AllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocationCommand) MoveAllocationCommand(org.opensearch.cluster.routing.allocation.command.MoveAllocationCommand) AllocateEmptyPrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand) AllocateEmptyPrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand) Matchers.containsString(org.hamcrest.Matchers.containsString) Logger(org.apache.logging.log4j.Logger) Settings(org.opensearch.common.settings.Settings) ClusterRerouteResponse(org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse)

Aggregations

ClusterRerouteResponse (org.opensearch.action.admin.cluster.reroute.ClusterRerouteResponse)4 Matchers.containsString (org.hamcrest.Matchers.containsString)3 ClusterHealthResponse (org.opensearch.action.admin.cluster.health.ClusterHealthResponse)3 MoveAllocationCommand (org.opensearch.cluster.routing.allocation.command.MoveAllocationCommand)3 Settings (org.opensearch.common.settings.Settings)2 ArrayList (java.util.ArrayList)1 Logger (org.apache.logging.log4j.Logger)1 ActionFuture (org.opensearch.action.ActionFuture)1 ClusterStateResponse (org.opensearch.action.admin.cluster.state.ClusterStateResponse)1 ClusterInfoService (org.opensearch.cluster.ClusterInfoService)1 InternalClusterInfoService (org.opensearch.cluster.InternalClusterInfoService)1 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)1 RoutingTable (org.opensearch.cluster.routing.RoutingTable)1 RerouteExplanation (org.opensearch.cluster.routing.allocation.RerouteExplanation)1 RoutingExplanations (org.opensearch.cluster.routing.allocation.RoutingExplanations)1 AllocateEmptyPrimaryAllocationCommand (org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand)1 AllocationCommand (org.opensearch.cluster.routing.allocation.command.AllocationCommand)1 TermsQueryBuilder (org.opensearch.index.query.TermsQueryBuilder)1 MockLogAppender (org.opensearch.test.MockLogAppender)1