Search in sources :

Example 1 with ClusterInfoService

use of org.opensearch.cluster.ClusterInfoService in project OpenSearch by opensearch-project.

the class DiskThresholdDeciderIT method refreshDiskUsage.

private void refreshDiskUsage() {
    final ClusterInfoService clusterInfoService = internalCluster().getCurrentMasterNodeInstance(ClusterInfoService.class);
    ((InternalClusterInfoService) clusterInfoService).refresh();
    // even though it's now possible to achieve better balance, so we have to do an explicit reroute. TODO fix this?
    if (StreamSupport.stream(clusterInfoService.getClusterInfo().getNodeMostAvailableDiskUsages().values().spliterator(), false).allMatch(cur -> cur.value.getFreeBytes() > WATERMARK_BYTES)) {
        assertAcked(client().admin().cluster().prepareReroute());
    }
    assertFalse(client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForNoRelocatingShards(true).setWaitForNoInitializingShards(true).get().isTimedOut());
}
Also used : InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService)

Example 2 with ClusterInfoService

use of org.opensearch.cluster.ClusterInfoService in project OpenSearch by opensearch-project.

the class DiskThresholdDeciderIT method testHighWatermarkNotExceeded.

public void testHighWatermarkNotExceeded() throws Exception {
    internalCluster().startMasterOnlyNode();
    internalCluster().startDataOnlyNode();
    final String dataNodeName = internalCluster().startDataOnlyNode();
    ensureStableCluster(3);
    final InternalClusterInfoService clusterInfoService = (InternalClusterInfoService) internalCluster().getCurrentMasterNodeInstance(ClusterInfoService.class);
    internalCluster().getCurrentMasterNodeInstance(ClusterService.class).addListener(event -> clusterInfoService.refresh());
    final String dataNode0Id = internalCluster().getInstance(NodeEnvironment.class, dataNodeName).nodeId();
    final Path dataNode0Path = internalCluster().getInstance(Environment.class, dataNodeName).dataFiles()[0];
    final String indexName = randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
    createIndex(indexName, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 6).put(INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING.getKey(), "0ms").build());
    final long minShardSize = createReasonableSizedShards(indexName);
    // reduce disk size of node 0 so that no shards fit below the high watermark, forcing all shards onto the other data node
    // (subtract the translog size since the disk threshold decider ignores this and may therefore move the shard back again)
    fileSystemProvider.getTestFileStore(dataNode0Path).setTotalSpace(minShardSize + WATERMARK_BYTES - 1L);
    assertBusyWithDiskUsageRefresh(dataNode0Id, indexName, empty());
    // increase disk size of node 0 to allow just enough room for one shard, and check that it's rebalanced back
    fileSystemProvider.getTestFileStore(dataNode0Path).setTotalSpace(minShardSize + WATERMARK_BYTES + 1L);
    assertBusyWithDiskUsageRefresh(dataNode0Id, indexName, hasSize(1));
}
Also used : FilterPath(org.apache.lucene.mockfile.FilterPath) Path(java.nio.file.Path) ClusterService(org.opensearch.cluster.service.ClusterService) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) NodeEnvironment(org.opensearch.env.NodeEnvironment) InternalClusterInfoService(org.opensearch.cluster.InternalClusterInfoService)

Example 3 with ClusterInfoService

use of org.opensearch.cluster.ClusterInfoService in project OpenSearch by opensearch-project.

the class DiskThresholdDeciderTests method testDiskThresholdWithAbsoluteSizes.

public void testDiskThresholdWithAbsoluteSizes() {
    Settings diskSettings = Settings.builder().put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), true).put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "30b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "9b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING.getKey(), "5b").build();
    ImmutableOpenMap.Builder<String, DiskUsage> usagesBuilder = ImmutableOpenMap.builder();
    // 90% used
    usagesBuilder.put("node1", new DiskUsage("node1", "n1", "/dev/null", 100, 10));
    // 90% used
    usagesBuilder.put("node2", new DiskUsage("node2", "n2", "/dev/null", 100, 10));
    // 40% used
    usagesBuilder.put("node3", new DiskUsage("node3", "n3", "/dev/null", 100, 60));
    // 20% used
    usagesBuilder.put("node4", new DiskUsage("node4", "n4", "/dev/null", 100, 80));
    // 15% used
    usagesBuilder.put("node5", new DiskUsage("node5", "n5", "/dev/null", 100, 85));
    ImmutableOpenMap<String, DiskUsage> usages = usagesBuilder.build();
    ImmutableOpenMap.Builder<String, Long> shardSizesBuilder = ImmutableOpenMap.builder();
    // 10 bytes
    shardSizesBuilder.put("[test][0][p]", 10L);
    shardSizesBuilder.put("[test][0][r]", 10L);
    ImmutableOpenMap<String, Long> shardSizes = shardSizesBuilder.build();
    final ClusterInfo clusterInfo = new DevNullClusterInfo(usages, usages, shardSizes);
    ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
    AllocationDeciders deciders = new AllocationDeciders(new HashSet<>(Arrays.asList(new SameShardAllocationDecider(Settings.EMPTY, clusterSettings), makeDecider(diskSettings))));
    ClusterInfoService cis = () -> {
        logger.info("--> calling fake getClusterInfo");
        return clusterInfo;
    };
    AllocationService strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), cis, EmptySnapshotsInfoService.INSTANCE);
    Metadata metadata = Metadata.builder().put(IndexMetadata.builder("test").settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(2)).build();
    RoutingTable initialRoutingTable = RoutingTable.builder().addAsNew(metadata.index("test")).build();
    ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).metadata(metadata).routingTable(initialRoutingTable).build();
    logger.info("--> adding node1 and node2 node");
    clusterState = ClusterState.builder(clusterState).nodes(DiscoveryNodes.builder().add(newNode("node1")).add(newNode("node2"))).build();
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Primary should initialize, even though both nodes are over the limit initialize
    assertThat(clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size(), equalTo(1));
    String nodeWithPrimary, nodeWithoutPrimary;
    if (clusterState.getRoutingNodes().node("node1").size() == 1) {
        nodeWithPrimary = "node1";
        nodeWithoutPrimary = "node2";
    } else {
        nodeWithPrimary = "node2";
        nodeWithoutPrimary = "node1";
    }
    logger.info("--> nodeWithPrimary: {}", nodeWithPrimary);
    logger.info("--> nodeWithoutPrimary: {}", nodeWithoutPrimary);
    // Make node without the primary now habitable to replicas
    usagesBuilder = ImmutableOpenMap.builder(usages);
    // 65% used
    usagesBuilder.put(nodeWithoutPrimary, new DiskUsage(nodeWithoutPrimary, "", "/dev/null", 100, 35));
    usages = usagesBuilder.build();
    final ClusterInfo clusterInfo2 = new DevNullClusterInfo(usages, usages, shardSizes);
    cis = () -> {
        logger.info("--> calling fake getClusterInfo");
        return clusterInfo2;
    };
    strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), cis, EmptySnapshotsInfoService.INSTANCE);
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Now the replica should be able to initialize
    assertThat(clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size(), equalTo(2));
    logger.info("--> start the shards (primaries)");
    clusterState = startInitializingShardsAndReroute(strategy, clusterState);
    logShardStates(clusterState);
    // Assert that we're able to start the primary and replica, since they were both initializing
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.STARTED).size(), equalTo(2));
    // Assert that node1 got a single shard (the primary), even though its disk usage is too high
    assertThat(clusterState.getRoutingNodes().node("node1").size(), equalTo(1));
    // Assert that node2 got a single shard (a replica)
    assertThat(clusterState.getRoutingNodes().node("node2").size(), equalTo(1));
    // Assert that one replica is still unassigned
    // assertThat(clusterState.routingNodes().shardsWithState(ShardRoutingState.UNASSIGNED).size(), equalTo(1));
    logger.info("--> adding node3");
    clusterState = ClusterState.builder(clusterState).nodes(DiscoveryNodes.builder(clusterState.nodes()).add(newNode("node3"))).build();
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Assert that the replica is initialized now that node3 is available with enough space
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.STARTED).size(), equalTo(2));
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.INITIALIZING).size(), equalTo(1));
    logger.info("--> start the shards (replicas)");
    clusterState = startInitializingShardsAndReroute(strategy, clusterState);
    logShardStates(clusterState);
    // Assert that all replicas could be started
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.STARTED).size(), equalTo(3));
    assertThat(clusterState.getRoutingNodes().node("node1").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node2").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node3").size(), equalTo(1));
    logger.info("--> changing decider settings");
    // Set the low threshold to 60 instead of 70
    // Set the high threshold to 70 instead of 80
    // node2 now should not have new shards allocated to it, but shards can remain
    diskSettings = Settings.builder().put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), true).put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "40b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "30b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING.getKey(), "20b").build();
    deciders = new AllocationDeciders(new HashSet<>(Arrays.asList(new SameShardAllocationDecider(Settings.EMPTY, clusterSettings), makeDecider(diskSettings))));
    strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), cis, EmptySnapshotsInfoService.INSTANCE);
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Shards remain started
    assertThat(clusterState.getRoutingNodes().shardsWithState(STARTED).size(), equalTo(3));
    assertThat(clusterState.getRoutingNodes().node("node1").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node2").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node3").size(), equalTo(1));
    logger.info("--> changing settings again");
    // Set the low threshold to 50 instead of 60
    // Set the high threshold to 60 instead of 70
    // node2 now should not have new shards allocated to it, and shards cannot remain
    diskSettings = Settings.builder().put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), true).put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "50b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "40b").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING.getKey(), "30b").build();
    deciders = new AllocationDeciders(new HashSet<>(Arrays.asList(new SameShardAllocationDecider(Settings.EMPTY, clusterSettings), makeDecider(diskSettings))));
    strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), cis, EmptySnapshotsInfoService.INSTANCE);
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Shards remain started
    assertThat(clusterState.getRoutingNodes().shardsWithState(STARTED).size(), equalTo(3));
    assertThat(clusterState.getRoutingNodes().node("node1").size(), equalTo(1));
    // Shard hasn't been moved off of node2 yet because there's nowhere for it to go
    assertThat(clusterState.getRoutingNodes().node("node2").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node3").size(), equalTo(1));
    logger.info("--> adding node4");
    clusterState = ClusterState.builder(clusterState).nodes(DiscoveryNodes.builder(clusterState.nodes()).add(newNode("node4"))).build();
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Shards remain started
    assertThat(clusterState.getRoutingNodes().shardsWithState(STARTED).size(), equalTo(2));
    // One shard is relocating off of node1
    assertThat(clusterState.getRoutingNodes().shardsWithState(RELOCATING).size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size(), equalTo(1));
    logger.info("--> apply INITIALIZING shards");
    clusterState = startInitializingShardsAndReroute(strategy, clusterState);
    logShardStates(clusterState);
    // primary shard already has been relocated away
    assertThat(clusterState.getRoutingNodes().node(nodeWithPrimary).size(), equalTo(0));
    // node with increased space still has its shard
    assertThat(clusterState.getRoutingNodes().node(nodeWithoutPrimary).size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node3").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node4").size(), equalTo(1));
    logger.info("--> adding node5");
    clusterState = ClusterState.builder(clusterState).nodes(DiscoveryNodes.builder(clusterState.nodes()).add(newNode("node5"))).build();
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // Shards remain started on node3 and node4
    assertThat(clusterState.getRoutingNodes().shardsWithState(STARTED).size(), equalTo(2));
    // One shard is relocating off of node2 now
    assertThat(clusterState.getRoutingNodes().shardsWithState(RELOCATING).size(), equalTo(1));
    // Initializing on node5
    assertThat(clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size(), equalTo(1));
    logger.info("--> apply INITIALIZING shards");
    clusterState = startInitializingShardsAndReroute(strategy, clusterState);
    logger.info("--> final cluster state:");
    logShardStates(clusterState);
    // Node1 still has no shards because it has no space for them
    assertThat(clusterState.getRoutingNodes().node("node1").size(), equalTo(0));
    // Node5 is available now, so the shard is moved off of node2
    assertThat(clusterState.getRoutingNodes().node("node2").size(), equalTo(0));
    assertThat(clusterState.getRoutingNodes().node("node3").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node4").size(), equalTo(1));
    assertThat(clusterState.getRoutingNodes().node("node5").size(), equalTo(1));
}
Also used : TestGatewayAllocator(org.opensearch.test.gateway.TestGatewayAllocator) ClusterState(org.opensearch.cluster.ClusterState) ClusterSettings(org.opensearch.common.settings.ClusterSettings) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) BalancedShardsAllocator(org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) Matchers.containsString(org.hamcrest.Matchers.containsString) DiskUsage(org.opensearch.cluster.DiskUsage) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) ClusterInfo(org.opensearch.cluster.ClusterInfo) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) Settings(org.opensearch.common.settings.Settings) DiskThresholdSettings(org.opensearch.cluster.routing.allocation.DiskThresholdSettings) ClusterSettings(org.opensearch.common.settings.ClusterSettings) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) HashSet(java.util.HashSet) IntHashSet(com.carrotsearch.hppc.IntHashSet)

Example 4 with ClusterInfoService

use of org.opensearch.cluster.ClusterInfoService in project OpenSearch by opensearch-project.

the class DiskThresholdDeciderTests method testDiskThresholdWithSnapshotShardSizes.

public void testDiskThresholdWithSnapshotShardSizes() {
    final long shardSizeInBytes = randomBoolean() ? 10L : 50L;
    logger.info("--> using shard size [{}]", shardSizeInBytes);
    final Settings diskSettings = Settings.builder().put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), true).put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "90%").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "95%").build();
    final ImmutableOpenMap.Builder<String, DiskUsage> usagesBuilder = ImmutableOpenMap.builder();
    // 79% used
    usagesBuilder.put("node1", new DiskUsage("node1", "n1", "/dev/null", 100, 21));
    // 99% used
    usagesBuilder.put("node2", new DiskUsage("node2", "n2", "/dev/null", 100, 1));
    final ImmutableOpenMap<String, DiskUsage> usages = usagesBuilder.build();
    final ClusterInfoService clusterInfoService = () -> new DevNullClusterInfo(usages, usages, ImmutableOpenMap.of());
    final AllocationDeciders deciders = new AllocationDeciders(new HashSet<>(Arrays.asList(new RestoreInProgressAllocationDecider(), new SameShardAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)), makeDecider(diskSettings))));
    final Snapshot snapshot = new Snapshot("_repository", new SnapshotId("_snapshot_name", UUIDs.randomBase64UUID(random())));
    final IndexId indexId = new IndexId("_indexid_name", UUIDs.randomBase64UUID(random()));
    final ShardId shardId = new ShardId(new Index("test", IndexMetadata.INDEX_UUID_NA_VALUE), 0);
    final Metadata metadata = Metadata.builder().put(IndexMetadata.builder("test").settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(0).putInSyncAllocationIds(0, singleton(AllocationId.newInitializing().getId()))).build();
    final RoutingTable routingTable = RoutingTable.builder().addAsNewRestore(metadata.index("test"), new RecoverySource.SnapshotRecoverySource("_restore_uuid", snapshot, Version.CURRENT, indexId), new IntHashSet()).build();
    final ImmutableOpenMap.Builder<ShardId, RestoreInProgress.ShardRestoreStatus> shards = ImmutableOpenMap.builder();
    shards.put(shardId, new RestoreInProgress.ShardRestoreStatus("node1"));
    final RestoreInProgress.Builder restores = new RestoreInProgress.Builder().add(new RestoreInProgress.Entry("_restore_uuid", snapshot, RestoreInProgress.State.INIT, singletonList("test"), shards.build()));
    ClusterState clusterState = ClusterState.builder(new ClusterName(getTestName())).metadata(metadata).routingTable(routingTable).putCustom(RestoreInProgress.TYPE, restores.build()).nodes(// node2 is added because DiskThresholdDecider
    DiscoveryNodes.builder().add(newNode("node1")).add(newNode("node2"))).build();
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).stream().map(ShardRouting::unassignedInfo).allMatch(unassignedInfo -> Reason.NEW_INDEX_RESTORED.equals(unassignedInfo.getReason())), is(true));
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).stream().map(ShardRouting::unassignedInfo).allMatch(unassignedInfo -> AllocationStatus.NO_ATTEMPT.equals(unassignedInfo.getLastAllocationStatus())), is(true));
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).size(), equalTo(1));
    final AtomicReference<SnapshotShardSizeInfo> snapshotShardSizeInfoRef = new AtomicReference<>(SnapshotShardSizeInfo.EMPTY);
    final AllocationService strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), clusterInfoService, snapshotShardSizeInfoRef::get);
    // reroute triggers snapshot shard size fetching
    clusterState = strategy.reroute(clusterState, "reroute");
    logShardStates(clusterState);
    // shard cannot be assigned yet as the snapshot shard size is unknown
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).stream().map(ShardRouting::unassignedInfo).allMatch(unassignedInfo -> AllocationStatus.FETCHING_SHARD_DATA.equals(unassignedInfo.getLastAllocationStatus())), is(true));
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).size(), equalTo(1));
    final SnapshotShard snapshotShard = new SnapshotShard(snapshot, indexId, shardId);
    final ImmutableOpenMap.Builder<SnapshotShard, Long> snapshotShardSizes = ImmutableOpenMap.builder();
    final boolean shouldAllocate;
    if (randomBoolean()) {
        logger.info("--> simulating snapshot shards size retrieval success");
        snapshotShardSizes.put(snapshotShard, shardSizeInBytes);
        logger.info("--> shard allocation depends on its size");
        shouldAllocate = shardSizeInBytes < usages.get("node1").getFreeBytes();
    } else {
        logger.info("--> simulating snapshot shards size retrieval failure");
        snapshotShardSizes.put(snapshotShard, ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE);
        logger.info("--> shard is always allocated when its size could not be retrieved");
        shouldAllocate = true;
    }
    snapshotShardSizeInfoRef.set(new SnapshotShardSizeInfo(snapshotShardSizes.build()));
    // reroute uses the previous snapshot shard size
    clusterState = startInitializingShardsAndReroute(strategy, clusterState);
    logShardStates(clusterState);
    assertThat(clusterState.getRoutingNodes().shardsWithState(UNASSIGNED).size(), equalTo(shouldAllocate ? 0 : 1));
    assertThat(clusterState.getRoutingNodes().shardsWithState("test", INITIALIZING, STARTED).size(), equalTo(shouldAllocate ? 1 : 0));
}
Also used : ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) Arrays(java.util.Arrays) INITIALIZING(org.opensearch.cluster.routing.ShardRoutingState.INITIALIZING) Metadata(org.opensearch.cluster.metadata.Metadata) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) Version(org.opensearch.Version) AllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocationCommand) MoveAllocationCommand(org.opensearch.cluster.routing.allocation.command.MoveAllocationCommand) Collections.singletonList(java.util.Collections.singletonList) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) IndexId(org.opensearch.repositories.IndexId) Collections.singleton(java.util.Collections.singleton) OpenSearchAllocationTestCase(org.opensearch.cluster.OpenSearchAllocationTestCase) Map(java.util.Map) Matchers.nullValue(org.hamcrest.Matchers.nullValue) BalancedShardsAllocator(org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) DiskUsage(org.opensearch.cluster.DiskUsage) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) ClusterInfo(org.opensearch.cluster.ClusterInfo) Reason(org.opensearch.cluster.routing.UnassignedInfo.Reason) Index(org.opensearch.index.Index) SnapshotId(org.opensearch.snapshots.SnapshotId) Settings(org.opensearch.common.settings.Settings) DiscoveryNodeRole(org.opensearch.cluster.node.DiscoveryNodeRole) RELOCATING(org.opensearch.cluster.routing.ShardRoutingState.RELOCATING) List(java.util.List) UNASSIGNED(org.opensearch.cluster.routing.ShardRoutingState.UNASSIGNED) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.is(org.hamcrest.Matchers.is) RoutingNode(org.opensearch.cluster.routing.RoutingNode) Matchers.containsString(org.hamcrest.Matchers.containsString) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) SnapshotShard(org.opensearch.snapshots.InternalSnapshotsInfoService.SnapshotShard) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) AllocationStatus(org.opensearch.cluster.routing.UnassignedInfo.AllocationStatus) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation) HashMap(java.util.HashMap) DiskThresholdSettings(org.opensearch.cluster.routing.allocation.DiskThresholdSettings) AtomicReference(java.util.concurrent.atomic.AtomicReference) RecoverySource(org.opensearch.cluster.routing.RecoverySource) HashSet(java.util.HashSet) CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING(org.opensearch.cluster.routing.allocation.decider.EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) ClusterState(org.opensearch.cluster.ClusterState) STARTED(org.opensearch.cluster.routing.ShardRoutingState.STARTED) SnapshotShardSizeInfo(org.opensearch.snapshots.SnapshotShardSizeInfo) RoutingNodes(org.opensearch.cluster.routing.RoutingNodes) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) UUIDs(org.opensearch.common.UUIDs) ClusterSettings(org.opensearch.common.settings.ClusterSettings) TestGatewayAllocator(org.opensearch.test.gateway.TestGatewayAllocator) Collections.emptyMap(java.util.Collections.emptyMap) Matchers.oneOf(org.hamcrest.Matchers.oneOf) AllocationCommands(org.opensearch.cluster.routing.allocation.command.AllocationCommands) AllocationId(org.opensearch.cluster.routing.AllocationId) IntHashSet(com.carrotsearch.hppc.IntHashSet) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ShardId(org.opensearch.index.shard.ShardId) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) EmptySnapshotsInfoService(org.opensearch.snapshots.EmptySnapshotsInfoService) Snapshot(org.opensearch.snapshots.Snapshot) ClusterName(org.opensearch.cluster.ClusterName) RestoreInProgress(org.opensearch.cluster.RestoreInProgress) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ClusterSettings(org.opensearch.common.settings.ClusterSettings) SnapshotShard(org.opensearch.snapshots.InternalSnapshotsInfoService.SnapshotShard) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) IntHashSet(com.carrotsearch.hppc.IntHashSet) Index(org.opensearch.index.Index) Matchers.containsString(org.hamcrest.Matchers.containsString) DiskUsage(org.opensearch.cluster.DiskUsage) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) SnapshotShardSizeInfo(org.opensearch.snapshots.SnapshotShardSizeInfo) ShardId(org.opensearch.index.shard.ShardId) ClusterName(org.opensearch.cluster.ClusterName) Settings(org.opensearch.common.settings.Settings) DiskThresholdSettings(org.opensearch.cluster.routing.allocation.DiskThresholdSettings) ClusterSettings(org.opensearch.common.settings.ClusterSettings) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) TestGatewayAllocator(org.opensearch.test.gateway.TestGatewayAllocator) IndexId(org.opensearch.repositories.IndexId) ClusterState(org.opensearch.cluster.ClusterState) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) BalancedShardsAllocator(org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) AtomicReference(java.util.concurrent.atomic.AtomicReference) Snapshot(org.opensearch.snapshots.Snapshot) SnapshotId(org.opensearch.snapshots.SnapshotId) RestoreInProgress(org.opensearch.cluster.RestoreInProgress) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting)

Example 5 with ClusterInfoService

use of org.opensearch.cluster.ClusterInfoService in project OpenSearch by opensearch-project.

the class DiskThresholdDeciderTests method testCanRemainWithShardRelocatingAway.

public void testCanRemainWithShardRelocatingAway() {
    Settings diskSettings = Settings.builder().put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), true).put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "60%").put(DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "70%").build();
    // We have an index with 2 primary shards each taking 40 bytes. Each node has 100 bytes available
    ImmutableOpenMap.Builder<String, DiskUsage> usagesBuilder = ImmutableOpenMap.builder();
    // 80% used
    usagesBuilder.put("node1", new DiskUsage("node1", "n1", "/dev/null", 100, 20));
    // 0% used
    usagesBuilder.put("node2", new DiskUsage("node2", "n2", "/dev/null", 100, 100));
    ImmutableOpenMap<String, DiskUsage> usages = usagesBuilder.build();
    ImmutableOpenMap.Builder<String, Long> shardSizesBuilder = ImmutableOpenMap.builder();
    shardSizesBuilder.put("[test][0][p]", 40L);
    shardSizesBuilder.put("[test][1][p]", 40L);
    shardSizesBuilder.put("[foo][0][p]", 10L);
    ImmutableOpenMap<String, Long> shardSizes = shardSizesBuilder.build();
    final ClusterInfo clusterInfo = new DevNullClusterInfo(usages, usages, shardSizes);
    DiskThresholdDecider diskThresholdDecider = makeDecider(diskSettings);
    Metadata metadata = Metadata.builder().put(IndexMetadata.builder("test").settings(settings(Version.CURRENT)).numberOfShards(2).numberOfReplicas(0)).put(IndexMetadata.builder("foo").settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(0)).build();
    RoutingTable initialRoutingTable = RoutingTable.builder().addAsNew(metadata.index("test")).addAsNew(metadata.index("foo")).build();
    DiscoveryNode discoveryNode1 = new DiscoveryNode("node1", buildNewFakeTransportAddress(), emptyMap(), MASTER_DATA_ROLES, Version.CURRENT);
    DiscoveryNode discoveryNode2 = new DiscoveryNode("node2", buildNewFakeTransportAddress(), emptyMap(), MASTER_DATA_ROLES, Version.CURRENT);
    DiscoveryNodes discoveryNodes = DiscoveryNodes.builder().add(discoveryNode1).add(discoveryNode2).build();
    ClusterState baseClusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).metadata(metadata).routingTable(initialRoutingTable).nodes(discoveryNodes).build();
    // Two shards consuming each 80% of disk space while 70% is allowed, so shard 0 isn't allowed here
    ShardRouting firstRouting = TestShardRouting.newShardRouting("test", 0, "node1", null, true, ShardRoutingState.STARTED);
    ShardRouting secondRouting = TestShardRouting.newShardRouting("test", 1, "node1", null, true, ShardRoutingState.STARTED);
    RoutingNode firstRoutingNode = new RoutingNode("node1", discoveryNode1, firstRouting, secondRouting);
    RoutingTable.Builder builder = RoutingTable.builder().add(IndexRoutingTable.builder(firstRouting.index()).addIndexShard(new IndexShardRoutingTable.Builder(firstRouting.shardId()).addShard(firstRouting).build()).addIndexShard(new IndexShardRoutingTable.Builder(secondRouting.shardId()).addShard(secondRouting).build()));
    ClusterState clusterState = ClusterState.builder(baseClusterState).routingTable(builder.build()).build();
    RoutingAllocation routingAllocation = new RoutingAllocation(null, new RoutingNodes(clusterState), clusterState, clusterInfo, null, System.nanoTime());
    routingAllocation.debugDecision(true);
    Decision decision = diskThresholdDecider.canRemain(firstRouting, firstRoutingNode, routingAllocation);
    assertThat(decision.type(), equalTo(Decision.Type.NO));
    assertThat(((Decision.Single) decision).getExplanation(), containsString("the shard cannot remain on this node because it is above the high watermark cluster setting " + "[cluster.routing.allocation.disk.watermark.high=70%] and there is less than the required [30.0%] free disk on node, " + "actual free: [20.0%]"));
    // Two shards consuming each 80% of disk space while 70% is allowed, but one is relocating, so shard 0 can stay
    firstRouting = TestShardRouting.newShardRouting("test", 0, "node1", null, true, ShardRoutingState.STARTED);
    secondRouting = TestShardRouting.newShardRouting("test", 1, "node1", "node2", true, ShardRoutingState.RELOCATING);
    ShardRouting fooRouting = TestShardRouting.newShardRouting("foo", 0, null, true, ShardRoutingState.UNASSIGNED);
    firstRoutingNode = new RoutingNode("node1", discoveryNode1, firstRouting, secondRouting);
    builder = RoutingTable.builder().add(IndexRoutingTable.builder(firstRouting.index()).addIndexShard(new IndexShardRoutingTable.Builder(firstRouting.shardId()).addShard(firstRouting).build()).addIndexShard(new IndexShardRoutingTable.Builder(secondRouting.shardId()).addShard(secondRouting).build()));
    clusterState = ClusterState.builder(baseClusterState).routingTable(builder.build()).build();
    routingAllocation = new RoutingAllocation(null, new RoutingNodes(clusterState), clusterState, clusterInfo, null, System.nanoTime());
    routingAllocation.debugDecision(true);
    decision = diskThresholdDecider.canRemain(firstRouting, firstRoutingNode, routingAllocation);
    assertThat(decision.type(), equalTo(Decision.Type.YES));
    assertEquals("there is enough disk on this node for the shard to remain, free: [60b]", ((Decision.Single) decision).getExplanation());
    decision = diskThresholdDecider.canAllocate(fooRouting, firstRoutingNode, routingAllocation);
    assertThat(decision.type(), equalTo(Decision.Type.NO));
    if (fooRouting.recoverySource().getType() == RecoverySource.Type.EMPTY_STORE) {
        assertThat(((Decision.Single) decision).getExplanation(), containsString("the node is above the high watermark cluster setting [cluster.routing.allocation.disk.watermark.high=70%], using " + "more disk space than the maximum allowed [70.0%], actual free: [20.0%]"));
    } else {
        assertThat(((Decision.Single) decision).getExplanation(), containsString("the node is above the low watermark cluster setting [cluster.routing.allocation.disk.watermark.low=60%], using more " + "disk space than the maximum allowed [60.0%], actual free: [20.0%]"));
    }
    // Creating AllocationService instance and the services it depends on...
    ClusterInfoService cis = () -> {
        logger.info("--> calling fake getClusterInfo");
        return clusterInfo;
    };
    AllocationDeciders deciders = new AllocationDeciders(new HashSet<>(Arrays.asList(new SameShardAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)), diskThresholdDecider)));
    AllocationService strategy = new AllocationService(deciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), cis, EmptySnapshotsInfoService.INSTANCE);
    // Ensure that the reroute call doesn't alter the routing table, since the first primary is relocating away
    // and therefor we will have sufficient disk space on node1.
    ClusterState result = strategy.reroute(clusterState, "reroute");
    assertThat(result, equalTo(clusterState));
    assertThat(result.routingTable().index("test").getShards().get(0).primaryShard().state(), equalTo(STARTED));
    assertThat(result.routingTable().index("test").getShards().get(0).primaryShard().currentNodeId(), equalTo("node1"));
    assertThat(result.routingTable().index("test").getShards().get(0).primaryShard().relocatingNodeId(), nullValue());
    assertThat(result.routingTable().index("test").getShards().get(1).primaryShard().state(), equalTo(RELOCATING));
    assertThat(result.routingTable().index("test").getShards().get(1).primaryShard().currentNodeId(), equalTo("node1"));
    assertThat(result.routingTable().index("test").getShards().get(1).primaryShard().relocatingNodeId(), equalTo("node2"));
}
Also used : IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) ClusterSettings(org.opensearch.common.settings.ClusterSettings) RoutingNodes(org.opensearch.cluster.routing.RoutingNodes) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) Matchers.containsString(org.hamcrest.Matchers.containsString) DiskUsage(org.opensearch.cluster.DiskUsage) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) RoutingNode(org.opensearch.cluster.routing.RoutingNode) Settings(org.opensearch.common.settings.Settings) DiskThresholdSettings(org.opensearch.cluster.routing.allocation.DiskThresholdSettings) ClusterSettings(org.opensearch.common.settings.ClusterSettings) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) TestGatewayAllocator(org.opensearch.test.gateway.TestGatewayAllocator) ClusterState(org.opensearch.cluster.ClusterState) ClusterInfoService(org.opensearch.cluster.ClusterInfoService) BalancedShardsAllocator(org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) ClusterInfo(org.opensearch.cluster.ClusterInfo) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation)

Aggregations

ClusterInfoService (org.opensearch.cluster.ClusterInfoService)15 ClusterState (org.opensearch.cluster.ClusterState)11 Settings (org.opensearch.common.settings.Settings)11 ClusterInfo (org.opensearch.cluster.ClusterInfo)10 DiskUsage (org.opensearch.cluster.DiskUsage)10 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)10 ImmutableOpenMap (org.opensearch.common.collect.ImmutableOpenMap)10 Matchers.containsString (org.hamcrest.Matchers.containsString)9 Metadata (org.opensearch.cluster.metadata.Metadata)9 IndexRoutingTable (org.opensearch.cluster.routing.IndexRoutingTable)9 IndexShardRoutingTable (org.opensearch.cluster.routing.IndexShardRoutingTable)9 RoutingTable (org.opensearch.cluster.routing.RoutingTable)9 AllocationService (org.opensearch.cluster.routing.allocation.AllocationService)9 DiskThresholdSettings (org.opensearch.cluster.routing.allocation.DiskThresholdSettings)9 BalancedShardsAllocator (org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator)9 ClusterSettings (org.opensearch.common.settings.ClusterSettings)9 TestGatewayAllocator (org.opensearch.test.gateway.TestGatewayAllocator)9 ShardRouting (org.opensearch.cluster.routing.ShardRouting)6 TestShardRouting (org.opensearch.cluster.routing.TestShardRouting)5 InternalClusterInfoService (org.opensearch.cluster.InternalClusterInfoService)4