Search in sources :

Example 1 with SameShardAllocationDecider

use of org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider in project elasticsearch by elastic.

the class ClusterModule method createAllocationDeciders.

// TODO: this is public so allocation benchmark can access the default deciders...can we do that in another way?
/** Return a new {@link AllocationDecider} instance with builtin deciders as well as those from plugins. */
public static Collection<AllocationDecider> createAllocationDeciders(Settings settings, ClusterSettings clusterSettings, List<ClusterPlugin> clusterPlugins) {
    // collect deciders by class so that we can detect duplicates
    Map<Class, AllocationDecider> deciders = new LinkedHashMap<>();
    addAllocationDecider(deciders, new MaxRetryAllocationDecider(settings));
    addAllocationDecider(deciders, new ReplicaAfterPrimaryActiveAllocationDecider(settings));
    addAllocationDecider(deciders, new RebalanceOnlyWhenActiveAllocationDecider(settings));
    addAllocationDecider(deciders, new ClusterRebalanceAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new ConcurrentRebalanceAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new EnableAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new NodeVersionAllocationDecider(settings));
    addAllocationDecider(deciders, new SnapshotInProgressAllocationDecider(settings));
    addAllocationDecider(deciders, new FilterAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new SameShardAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new DiskThresholdDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new ThrottlingAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new ShardsLimitAllocationDecider(settings, clusterSettings));
    addAllocationDecider(deciders, new AwarenessAllocationDecider(settings, clusterSettings));
    clusterPlugins.stream().flatMap(p -> p.createAllocationDeciders(settings, clusterSettings).stream()).forEach(d -> addAllocationDecider(deciders, d));
    return deciders.values();
}
Also used : MetaData(org.elasticsearch.cluster.metadata.MetaData) DelayedAllocationService(org.elasticsearch.cluster.routing.DelayedAllocationService) IngestMetadata(org.elasticsearch.ingest.IngestMetadata) AwarenessAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider) Property(org.elasticsearch.common.settings.Setting.Property) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) AllocationService(org.elasticsearch.cluster.routing.allocation.AllocationService) Reader(org.elasticsearch.common.io.stream.Writeable.Reader) ConcurrentRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ConcurrentRebalanceAllocationDecider) ClusterPlugin(org.elasticsearch.plugins.ClusterPlugin) Settings(org.elasticsearch.common.settings.Settings) SnapshotInProgressAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SnapshotInProgressAllocationDecider) Map(java.util.Map) TaskResultsService(org.elasticsearch.tasks.TaskResultsService) ParseField(org.elasticsearch.common.ParseField) NamedXContentRegistry(org.elasticsearch.common.xcontent.NamedXContentRegistry) ShardsLimitAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider) MappingUpdatedAction(org.elasticsearch.cluster.action.index.MappingUpdatedAction) BalancedShardsAllocator(org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) Setting(org.elasticsearch.common.settings.Setting) AbstractModule(org.elasticsearch.common.inject.AbstractModule) DiskThresholdDecider(org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider) Collection(java.util.Collection) NodeMappingRefreshAction(org.elasticsearch.cluster.action.index.NodeMappingRefreshAction) Objects(java.util.Objects) RebalanceOnlyWhenActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.RebalanceOnlyWhenActiveAllocationDecider) List(java.util.List) ShardStateAction(org.elasticsearch.cluster.action.shard.ShardStateAction) AllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider) NodeVersionAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider) FilterAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider) ThrottlingAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider) MetaDataCreateIndexService(org.elasticsearch.cluster.metadata.MetaDataCreateIndexService) ReplicaAfterPrimaryActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider) MaxRetryAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider) ClusterService(org.elasticsearch.cluster.service.ClusterService) NamedWriteable(org.elasticsearch.common.io.stream.NamedWriteable) IndexGraveyard(org.elasticsearch.cluster.metadata.IndexGraveyard) HashMap(java.util.HashMap) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) MetaDataUpdateSettingsService(org.elasticsearch.cluster.metadata.MetaDataUpdateSettingsService) NamedWriteableRegistry(org.elasticsearch.common.io.stream.NamedWriteableRegistry) AllocationDeciders(org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders) ClusterRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider) EnableAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider) RepositoriesMetaData(org.elasticsearch.cluster.metadata.RepositoriesMetaData) MetaDataIndexAliasesService(org.elasticsearch.cluster.metadata.MetaDataIndexAliasesService) ShardsAllocator(org.elasticsearch.cluster.routing.allocation.allocator.ShardsAllocator) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) MetaDataIndexTemplateService(org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService) ScriptMetaData(org.elasticsearch.script.ScriptMetaData) MetaDataMappingService(org.elasticsearch.cluster.metadata.MetaDataMappingService) RoutingService(org.elasticsearch.cluster.routing.RoutingService) MetaDataDeleteIndexService(org.elasticsearch.cluster.metadata.MetaDataDeleteIndexService) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) Writeable(org.elasticsearch.common.io.stream.Writeable) GatewayAllocator(org.elasticsearch.gateway.GatewayAllocator) MetaDataIndexStateService(org.elasticsearch.cluster.metadata.MetaDataIndexStateService) Entry(org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry) SnapshotInProgressAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SnapshotInProgressAllocationDecider) EnableAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider) RebalanceOnlyWhenActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.RebalanceOnlyWhenActiveAllocationDecider) ThrottlingAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider) MaxRetryAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider) ReplicaAfterPrimaryActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider) LinkedHashMap(java.util.LinkedHashMap) ClusterRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) FilterAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider) DiskThresholdDecider(org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider) ShardsLimitAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider) AwarenessAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider) NodeVersionAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider) AwarenessAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) ConcurrentRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ConcurrentRebalanceAllocationDecider) SnapshotInProgressAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SnapshotInProgressAllocationDecider) ShardsLimitAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider) RebalanceOnlyWhenActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.RebalanceOnlyWhenActiveAllocationDecider) AllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider) NodeVersionAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider) FilterAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider) ThrottlingAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider) ReplicaAfterPrimaryActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider) MaxRetryAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider) ClusterRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider) EnableAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider) ConcurrentRebalanceAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ConcurrentRebalanceAllocationDecider)

Example 2 with SameShardAllocationDecider

use of org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider in project elasticsearch by elastic.

the class FilterAllocationDeciderTests method testFilterInitialRecovery.

public void testFilterInitialRecovery() {
    ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
    FilterAllocationDecider filterAllocationDecider = new FilterAllocationDecider(Settings.EMPTY, clusterSettings);
    AllocationDeciders allocationDeciders = new AllocationDeciders(Settings.EMPTY, Arrays.asList(filterAllocationDecider, new SameShardAllocationDecider(Settings.EMPTY, clusterSettings), new ReplicaAfterPrimaryActiveAllocationDecider(Settings.EMPTY)));
    AllocationService service = new AllocationService(Settings.builder().build(), allocationDeciders, new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), EmptyClusterInfoService.INSTANCE);
    ClusterState state = createInitialClusterState(service, Settings.builder().put("index.routing.allocation.initial_recovery._id", "node2").build());
    RoutingTable routingTable = state.routingTable();
    // we can initally only allocate on node2
    assertEquals(routingTable.index("idx").shard(0).shards().get(0).state(), INITIALIZING);
    assertEquals(routingTable.index("idx").shard(0).shards().get(0).currentNodeId(), "node2");
    routingTable = service.applyFailedShard(state, routingTable.index("idx").shard(0).shards().get(0)).routingTable();
    state = ClusterState.builder(state).routingTable(routingTable).build();
    assertEquals(routingTable.index("idx").shard(0).shards().get(0).state(), UNASSIGNED);
    assertNull(routingTable.index("idx").shard(0).shards().get(0).currentNodeId());
    // after failing the shard we are unassigned since the node is blacklisted and we can't initialize on the other node
    RoutingAllocation allocation = new RoutingAllocation(allocationDeciders, state.getRoutingNodes(), state, null, 0, false);
    allocation.debugDecision(true);
    Decision.Single decision = (Decision.Single) filterAllocationDecider.canAllocate(routingTable.index("idx").shard(0).primaryShard(), state.getRoutingNodes().node("node2"), allocation);
    assertEquals(Type.YES, decision.type());
    assertEquals("node passes include/exclude/require filters", decision.getExplanation());
    ShardRouting primaryShard = routingTable.index("idx").shard(0).primaryShard();
    decision = (Decision.Single) filterAllocationDecider.canAllocate(routingTable.index("idx").shard(0).primaryShard(), state.getRoutingNodes().node("node1"), allocation);
    assertEquals(Type.NO, decision.type());
    if (primaryShard.recoverySource().getType() == RecoverySource.Type.LOCAL_SHARDS) {
        assertEquals("initial allocation of the shrunken index is only allowed on nodes [_id:\"node2\"] that " + "hold a copy of every shard in the index", decision.getExplanation());
    } else {
        assertEquals("initial allocation of the index is only allowed on nodes [_id:\"node2\"]", decision.getExplanation());
    }
    state = service.reroute(state, "try allocate again");
    routingTable = state.routingTable();
    assertEquals(routingTable.index("idx").shard(0).primaryShard().state(), INITIALIZING);
    assertEquals(routingTable.index("idx").shard(0).primaryShard().currentNodeId(), "node2");
    state = service.applyStartedShards(state, routingTable.index("idx").shard(0).shardsWithState(INITIALIZING));
    routingTable = state.routingTable();
    // ok now we are started and can be allocated anywhere!! lets see...
    // first create another copy
    assertEquals(routingTable.index("idx").shard(0).replicaShards().get(0).state(), INITIALIZING);
    assertEquals(routingTable.index("idx").shard(0).replicaShards().get(0).currentNodeId(), "node1");
    state = service.applyStartedShards(state, routingTable.index("idx").shard(0).replicaShardsWithState(INITIALIZING));
    routingTable = state.routingTable();
    assertEquals(routingTable.index("idx").shard(0).replicaShards().get(0).state(), STARTED);
    assertEquals(routingTable.index("idx").shard(0).replicaShards().get(0).currentNodeId(), "node1");
    // now remove the node of the other copy and fail the current
    DiscoveryNode node1 = state.nodes().resolveNode("node1");
    state = service.deassociateDeadNodes(ClusterState.builder(state).nodes(DiscoveryNodes.builder(state.nodes()).remove("node1")).build(), true, "test");
    state = service.applyFailedShard(state, routingTable.index("idx").shard(0).primaryShard());
    // now bring back node1 and see it's assigned
    state = service.reroute(ClusterState.builder(state).nodes(DiscoveryNodes.builder(state.nodes()).add(node1)).build(), "test");
    routingTable = state.routingTable();
    assertEquals(routingTable.index("idx").shard(0).primaryShard().state(), INITIALIZING);
    assertEquals(routingTable.index("idx").shard(0).primaryShard().currentNodeId(), "node1");
    allocation = new RoutingAllocation(allocationDeciders, state.getRoutingNodes(), state, null, 0, false);
    allocation.debugDecision(true);
    decision = (Decision.Single) filterAllocationDecider.canAllocate(routingTable.index("idx").shard(0).shards().get(0), state.getRoutingNodes().node("node2"), allocation);
    assertEquals(Type.YES, decision.type());
    assertEquals("node passes include/exclude/require filters", decision.getExplanation());
    decision = (Decision.Single) filterAllocationDecider.canAllocate(routingTable.index("idx").shard(0).shards().get(0), state.getRoutingNodes().node("node1"), allocation);
    assertEquals(Type.YES, decision.type());
    assertEquals("node passes include/exclude/require filters", decision.getExplanation());
}
Also used : TestGatewayAllocator(org.elasticsearch.test.gateway.TestGatewayAllocator) ClusterState(org.elasticsearch.cluster.ClusterState) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) BalancedShardsAllocator(org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) AllocationDeciders(org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders) ReplicaAfterPrimaryActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider) Decision(org.elasticsearch.cluster.routing.allocation.decider.Decision) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) FilterAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 3 with SameShardAllocationDecider

use of org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider in project elasticsearch by elastic.

the class ReplicaShardAllocatorTests method testThrottleWhenAllocatingToMatchingNode.

/**
     * Tests when the node to allocate to due to matching is being throttled, we move the shard to ignored
     * to wait till throttling on it is done.
     */
public void testThrottleWhenAllocatingToMatchingNode() {
    RoutingAllocation allocation = onePrimaryOnNode1And1Replica(new AllocationDeciders(Settings.EMPTY, Arrays.asList(new TestAllocateDecision(Decision.YES), new SameShardAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)), new AllocationDecider(Settings.EMPTY) {

        @Override
        public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
            if (node.node().equals(node2)) {
                return Decision.THROTTLE;
            }
            return Decision.YES;
        }
    })));
    testAllocator.addData(node1, "MATCH", new StoreFileMetaData("file1", 10, "MATCH_CHECKSUM")).addData(node2, "MATCH", new StoreFileMetaData("file1", 10, "MATCH_CHECKSUM"));
    testAllocator.allocateUnassigned(allocation);
    assertThat(allocation.routingNodes().unassigned().ignored().size(), equalTo(1));
    assertThat(allocation.routingNodes().unassigned().ignored().get(0).shardId(), equalTo(shardId));
}
Also used : SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) RoutingNode(org.elasticsearch.cluster.routing.RoutingNode) StoreFileMetaData(org.elasticsearch.index.store.StoreFileMetaData) AllocationDeciders(org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders) RoutingAllocation(org.elasticsearch.cluster.routing.allocation.RoutingAllocation) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) TestShardRouting(org.elasticsearch.cluster.routing.TestShardRouting) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) AllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider) Decision(org.elasticsearch.cluster.routing.allocation.decider.Decision)

Example 4 with SameShardAllocationDecider

use of org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider in project elasticsearch by elastic.

the class SameShardRoutingTests method testForceAllocatePrimaryOnSameNodeNotAllowed.

public void testForceAllocatePrimaryOnSameNodeNotAllowed() {
    SameShardAllocationDecider decider = new SameShardAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS));
    ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomIntBetween(2, 4), 1);
    Index index = clusterState.getMetaData().index("idx").getIndex();
    ShardRouting primaryShard = clusterState.routingTable().index(index).shard(0).primaryShard();
    RoutingNode routingNode = clusterState.getRoutingNodes().node(primaryShard.currentNodeId());
    RoutingAllocation routingAllocation = new RoutingAllocation(new AllocationDeciders(Settings.EMPTY, Collections.emptyList()), new RoutingNodes(clusterState, false), clusterState, ClusterInfo.EMPTY, System.nanoTime(), false);
    // can't force allocate same shard copy to the same node
    ShardRouting newPrimary = TestShardRouting.newShardRouting(primaryShard.shardId(), null, true, ShardRoutingState.UNASSIGNED);
    Decision decision = decider.canForceAllocatePrimary(newPrimary, routingNode, routingAllocation);
    assertEquals(Decision.Type.NO, decision.type());
    // can force allocate to a different node
    RoutingNode unassignedNode = null;
    for (RoutingNode node : clusterState.getRoutingNodes()) {
        if (node.isEmpty()) {
            unassignedNode = node;
            break;
        }
    }
    decision = decider.canForceAllocatePrimary(newPrimary, unassignedNode, routingAllocation);
    assertEquals(Decision.Type.YES, decision.type());
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) RoutingNode(org.elasticsearch.cluster.routing.RoutingNode) RoutingNodes(org.elasticsearch.cluster.routing.RoutingNodes) Index(org.elasticsearch.index.Index) AllocationDeciders(org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) TestShardRouting(org.elasticsearch.cluster.routing.TestShardRouting) Decision(org.elasticsearch.cluster.routing.allocation.decider.Decision)

Example 5 with SameShardAllocationDecider

use of org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider in project elasticsearch by elastic.

the class RandomAllocationDeciderTests method testRandomDecisions.

/* This test will make random allocation decision on a growing and shrinking
     * cluster leading to a random distribution of the shards. After a certain
     * amount of iterations the test allows allocation unless the same shard is
     * already allocated on a node and balances the cluster to gain optimal
     * balance.*/
public void testRandomDecisions() {
    RandomAllocationDecider randomAllocationDecider = new RandomAllocationDecider(random());
    AllocationService strategy = new AllocationService(Settings.builder().build(), new AllocationDeciders(Settings.EMPTY, new HashSet<>(Arrays.asList(new SameShardAllocationDecider(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)), new ReplicaAfterPrimaryActiveAllocationDecider(Settings.EMPTY), randomAllocationDecider))), new TestGatewayAllocator(), new BalancedShardsAllocator(Settings.EMPTY), EmptyClusterInfoService.INSTANCE);
    int indices = scaledRandomIntBetween(1, 20);
    Builder metaBuilder = MetaData.builder();
    int maxNumReplicas = 1;
    int totalNumShards = 0;
    for (int i = 0; i < indices; i++) {
        int replicas = scaledRandomIntBetween(0, 6);
        maxNumReplicas = Math.max(maxNumReplicas, replicas + 1);
        int numShards = scaledRandomIntBetween(1, 20);
        totalNumShards += numShards * (replicas + 1);
        metaBuilder.put(IndexMetaData.builder("INDEX_" + i).settings(settings(Version.CURRENT)).numberOfShards(numShards).numberOfReplicas(replicas));
    }
    MetaData metaData = metaBuilder.build();
    RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
    for (int i = 0; i < indices; i++) {
        routingTableBuilder.addAsNew(metaData.index("INDEX_" + i));
    }
    RoutingTable initialRoutingTable = routingTableBuilder.build();
    ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).metaData(metaData).routingTable(initialRoutingTable).build();
    int numIters = scaledRandomIntBetween(5, 15);
    int nodeIdCounter = 0;
    int atMostNodes = scaledRandomIntBetween(Math.max(1, maxNumReplicas), 15);
    final boolean frequentNodes = randomBoolean();
    AllocationService.CommandsResult routingResult;
    for (int i = 0; i < numIters; i++) {
        logger.info("Start iteration [{}]", i);
        ClusterState.Builder stateBuilder = ClusterState.builder(clusterState);
        DiscoveryNodes.Builder newNodesBuilder = DiscoveryNodes.builder(clusterState.nodes());
        if (clusterState.nodes().getSize() <= atMostNodes && (nodeIdCounter == 0 || (frequentNodes ? frequently() : rarely()))) {
            int numNodes = scaledRandomIntBetween(1, 3);
            for (int j = 0; j < numNodes; j++) {
                logger.info("adding node [{}]", nodeIdCounter);
                newNodesBuilder.add(newNode("NODE_" + (nodeIdCounter++)));
            }
        }
        boolean nodesRemoved = false;
        if (nodeIdCounter > 1 && rarely()) {
            int nodeId = scaledRandomIntBetween(0, nodeIdCounter - 2);
            final String node = "NODE_" + nodeId;
            boolean safeToRemove = true;
            RoutingNode routingNode = clusterState.getRoutingNodes().node(node);
            for (ShardRouting shard : routingNode != null ? routingNode : Collections.<ShardRouting>emptyList()) {
                if (shard.active() && shard.primary()) {
                    // make sure there is an active replica to prevent from going red
                    if (clusterState.routingTable().shardRoutingTable(shard.shardId()).activeShards().size() <= 1) {
                        safeToRemove = false;
                        break;
                    }
                }
            }
            if (safeToRemove) {
                logger.info("removing node [{}]", nodeId);
                newNodesBuilder.remove(node);
                nodesRemoved = true;
            } else {
                logger.debug("not removing node [{}] as it holds a primary with no replacement", nodeId);
            }
        }
        stateBuilder.nodes(newNodesBuilder.build());
        clusterState = stateBuilder.build();
        if (nodesRemoved) {
            clusterState = strategy.deassociateDeadNodes(clusterState, true, "reroute");
        } else {
            clusterState = strategy.reroute(clusterState, "reroute");
        }
        if (clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size() > 0) {
            clusterState = strategy.applyStartedShards(clusterState, clusterState.getRoutingNodes().shardsWithState(INITIALIZING));
        }
    }
    logger.info("Fill up nodes such that every shard can be allocated");
    if (clusterState.nodes().getSize() < maxNumReplicas) {
        ClusterState.Builder stateBuilder = ClusterState.builder(clusterState);
        DiscoveryNodes.Builder newNodesBuilder = DiscoveryNodes.builder(clusterState.nodes());
        for (int j = 0; j < (maxNumReplicas - clusterState.nodes().getSize()); j++) {
            logger.info("adding node [{}]", nodeIdCounter);
            newNodesBuilder.add(newNode("NODE_" + (nodeIdCounter++)));
        }
        stateBuilder.nodes(newNodesBuilder.build());
        clusterState = stateBuilder.build();
    }
    randomAllocationDecider.alwaysSayYes = true;
    logger.info("now say YES to everything");
    int iterations = 0;
    do {
        iterations++;
        clusterState = strategy.reroute(clusterState, "reroute");
        if (clusterState.getRoutingNodes().shardsWithState(INITIALIZING).size() > 0) {
            clusterState = strategy.applyStartedShards(clusterState, clusterState.getRoutingNodes().shardsWithState(INITIALIZING));
        }
    } while (clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.INITIALIZING).size() != 0 || clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.UNASSIGNED).size() != 0 && iterations < 200);
    logger.info("Done Balancing after [{}] iterations. State:\n{}", iterations, clusterState);
    // we stop after 200 iterations if it didn't stabelize by then something is likely to be wrong
    assertThat("max num iteration exceeded", iterations, Matchers.lessThan(200));
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.INITIALIZING).size(), equalTo(0));
    assertThat(clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.UNASSIGNED).size(), equalTo(0));
    int shards = clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.STARTED).size();
    assertThat(shards, equalTo(totalNumShards));
    final int numNodes = clusterState.nodes().getSize();
    final int upperBound = (int) Math.round(((shards / numNodes) * 1.10));
    final int lowerBound = (int) Math.round(((shards / numNodes) * 0.90));
    for (int i = 0; i < nodeIdCounter; i++) {
        if (clusterState.getRoutingNodes().node("NODE_" + i) == null) {
            continue;
        }
        assertThat(clusterState.getRoutingNodes().node("NODE_" + i).size(), Matchers.anyOf(Matchers.anyOf(equalTo((shards / numNodes) + 1), equalTo((shards / numNodes) - 1), equalTo((shards / numNodes))), Matchers.allOf(Matchers.greaterThanOrEqualTo(lowerBound), Matchers.lessThanOrEqualTo(upperBound))));
    }
}
Also used : TestGatewayAllocator(org.elasticsearch.test.gateway.TestGatewayAllocator) ClusterState(org.elasticsearch.cluster.ClusterState) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) BalancedShardsAllocator(org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator) Builder(org.elasticsearch.cluster.metadata.MetaData.Builder) AllocationDeciders(org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders) ReplicaAfterPrimaryActiveAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider) SameShardAllocationDecider(org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) RoutingNode(org.elasticsearch.cluster.routing.RoutingNode) MetaData(org.elasticsearch.cluster.metadata.MetaData) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes) HashSet(java.util.HashSet)

Aggregations

AllocationDeciders (org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders)8 SameShardAllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider)8 ClusterSettings (org.elasticsearch.common.settings.ClusterSettings)8 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)5 BalancedShardsAllocator (org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator)5 ReplicaAfterPrimaryActiveAllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider)5 RoutingNode (org.elasticsearch.cluster.routing.RoutingNode)4 AllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider)4 ClusterState (org.elasticsearch.cluster.ClusterState)3 TestShardRouting (org.elasticsearch.cluster.routing.TestShardRouting)3 AllocationService (org.elasticsearch.cluster.routing.allocation.AllocationService)3 Decision (org.elasticsearch.cluster.routing.allocation.decider.Decision)3 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Map (java.util.Map)2 Objects (java.util.Objects)2