Search in sources :

Example 1 with Builder

use of org.elasticsearch.cluster.metadata.MetaData.Builder 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

HashSet (java.util.HashSet)1 ClusterState (org.elasticsearch.cluster.ClusterState)1 IndexMetaData (org.elasticsearch.cluster.metadata.IndexMetaData)1 MetaData (org.elasticsearch.cluster.metadata.MetaData)1 Builder (org.elasticsearch.cluster.metadata.MetaData.Builder)1 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)1 RoutingNode (org.elasticsearch.cluster.routing.RoutingNode)1 RoutingTable (org.elasticsearch.cluster.routing.RoutingTable)1 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)1 BalancedShardsAllocator (org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator)1 AllocationDeciders (org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders)1 ReplicaAfterPrimaryActiveAllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider)1 SameShardAllocationDecider (org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider)1 ClusterSettings (org.elasticsearch.common.settings.ClusterSettings)1 TestGatewayAllocator (org.elasticsearch.test.gateway.TestGatewayAllocator)1