@Test public void testSingleIndexShardFailed() { AllocationService strategy = createAllocationService( settingsBuilder().put("cluster.routing.allocation.concurrent_recoveries", 10).build()); logger.info("Building initial routing table"); MetaData metaData = MetaData.builder() .put(IndexMetaData.builder("test").numberOfShards(1).numberOfReplicas(0)) .build(); RoutingTable routingTable = RoutingTable.builder().addAsNew(metaData.index("test")).build(); ClusterState clusterState = ClusterState.builder().metaData(metaData).routingTable(routingTable).build(); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(0).currentNodeId(), nullValue()); logger.info("Adding one node and rerouting"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder().put(newNode("node1"))) .build(); RoutingTable prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).unassigned(), equalTo(false)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(INITIALIZING)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node1")); logger.info("Marking the shard as failed"); RoutingNodes routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyFailedShard( clusterState, routingNodes.node("node1").shardsWithState(INITIALIZING).get(0)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(0).currentNodeId(), nullValue()); }
@Test public void indexLevelShardsLimitAllocate() { AllocationService strategy = new AllocationService( settingsBuilder().put("cluster.routing.allocation.concurrent_recoveries", 10).build()); logger.info("Building initial routing table"); MetaData metaData = newMetaDataBuilder() .put( newIndexMetaDataBuilder("test") .settings( ImmutableSettings.settingsBuilder() .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 4) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1) .put(ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE, 2))) .build(); RoutingTable routingTable = routingTable().addAsNew(metaData.index("test")).build(); ClusterState clusterState = newClusterStateBuilder().metaData(metaData).routingTable(routingTable).build(); logger.info("Adding two nodes and performing rerouting"); clusterState = newClusterStateBuilder() .state(clusterState) .nodes(newNodesBuilder().put(newNode("node1")).put(newNode("node2"))) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat( clusterState .readOnlyRoutingNodes() .node("node1") .numberOfShardsWithState(ShardRoutingState.INITIALIZING), equalTo(2)); assertThat( clusterState .readOnlyRoutingNodes() .node("node2") .numberOfShardsWithState(ShardRoutingState.INITIALIZING), equalTo(2)); logger.info("Start the primary shards"); RoutingNodes routingNodes = clusterState.routingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat( clusterState .readOnlyRoutingNodes() .node("node1") .numberOfShardsWithState(ShardRoutingState.STARTED), equalTo(2)); assertThat( clusterState .readOnlyRoutingNodes() .node("node1") .numberOfShardsWithState(ShardRoutingState.INITIALIZING), equalTo(0)); assertThat( clusterState .readOnlyRoutingNodes() .node("node2") .numberOfShardsWithState(ShardRoutingState.STARTED), equalTo(2)); assertThat( clusterState .readOnlyRoutingNodes() .node("node2") .numberOfShardsWithState(ShardRoutingState.INITIALIZING), equalTo(0)); assertThat(clusterState.readOnlyRoutingNodes().unassigned().size(), equalTo(4)); logger.info("Do another reroute, make sure its still not allocated"); routingNodes = clusterState.routingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); }
@Test public void indexLevelShardsLimitRemain() { AllocationService strategy = new AllocationService( settingsBuilder() .put("cluster.routing.allocation.concurrent_recoveries", 10) .put("cluster.routing.allocation.node_initial_primaries_recoveries", 10) .put("cluster.routing.allocation.cluster_concurrent_rebalance", -1) .put("cluster.routing.allocation.balance.index", 0.0f) .put("cluster.routing.allocation.balance.replica", 1.0f) .put("cluster.routing.allocation.balance.primary", 0.0f) .build()); logger.info("Building initial routing table"); MetaData metaData = newMetaDataBuilder() .put( newIndexMetaDataBuilder("test") .settings( ImmutableSettings.settingsBuilder() .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 5) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0))) .build(); RoutingTable routingTable = routingTable().addAsNew(metaData.index("test")).build(); ClusterState clusterState = newClusterStateBuilder().metaData(metaData).routingTable(routingTable).build(); logger.info("Adding one node and reroute"); clusterState = newClusterStateBuilder() .state(clusterState) .nodes(newNodesBuilder().put(newNode("node1"))) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); logger.info("Start the primary shards"); RoutingNodes routingNodes = clusterState.routingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(clusterState.readOnlyRoutingNodes().numberOfShardsOfType(STARTED), equalTo(5)); logger.info("add another index with 5 shards"); metaData = newMetaDataBuilder() .metaData(metaData) .put( newIndexMetaDataBuilder("test1") .settings( ImmutableSettings.settingsBuilder() .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 5) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0))) .build(); routingTable = routingTable().routingTable(routingTable).addAsNew(metaData.index("test1")).build(); clusterState = newClusterStateBuilder() .state(clusterState) .metaData(metaData) .routingTable(routingTable) .build(); logger.info("Add another one node and reroute"); clusterState = newClusterStateBuilder() .state(clusterState) .nodes(newNodesBuilder().putAll(clusterState.nodes()).put(newNode("node2"))) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.routingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(clusterState.readOnlyRoutingNodes().numberOfShardsOfType(STARTED), equalTo(10)); for (MutableShardRouting shardRouting : clusterState.readOnlyRoutingNodes().node("node1")) { assertThat(shardRouting.index(), equalTo("test")); } for (MutableShardRouting shardRouting : clusterState.readOnlyRoutingNodes().node("node2")) { assertThat(shardRouting.index(), equalTo("test1")); } logger.info( "update " + ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE + " for test, see that things move"); metaData = newMetaDataBuilder() .metaData(metaData) .put( newIndexMetaDataBuilder("test") .settings( ImmutableSettings.settingsBuilder() .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 5) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) .put(ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE, 3))) .build(); clusterState = newClusterStateBuilder().state(clusterState).metaData(metaData).build(); logger.info("reroute after setting"); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat( clusterState.readOnlyRoutingNodes().node("node1").numberOfShardsWithState(STARTED), equalTo(3)); assertThat( clusterState.readOnlyRoutingNodes().node("node1").numberOfShardsWithState(RELOCATING), equalTo(2)); assertThat( clusterState.readOnlyRoutingNodes().node("node2").numberOfShardsWithState(RELOCATING), equalTo(2)); assertThat( clusterState.readOnlyRoutingNodes().node("node2").numberOfShardsWithState(STARTED), equalTo(3)); // the first move will destroy the balance and the balancer will move 2 shards from node2 to // node one right after // moving the nodes to node2 since we consider INITIALIZING nodes during rebalance routingNodes = clusterState.routingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); // now we are done compared to EvenShardCountAllocator since the Balancer is not soely based on // the average assertThat( clusterState.readOnlyRoutingNodes().node("node1").numberOfShardsWithState(STARTED), equalTo(5)); assertThat( clusterState.readOnlyRoutingNodes().node("node2").numberOfShardsWithState(STARTED), equalTo(5)); }
@Test public void testSingleIndexStartedShard() { AllocationService strategy = createAllocationService( settingsBuilder().put("cluster.routing.allocation.concurrent_recoveries", 10).build()); logger.info("Building initial routing table"); MetaData metaData = MetaData.builder() .put( IndexMetaData.builder("test") .settings(settings(Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(0)) .build(); RoutingTable routingTable = RoutingTable.builder().addAsNew(metaData.index("test")).build(); ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT) .metaData(metaData) .routingTable(routingTable) .build(); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(0).currentNodeId(), nullValue()); logger.info("Adding one node and performing rerouting"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder().put(newNode("node1"))) .build(); RoutingTable prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(INITIALIZING)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node1")); logger.info("Rerouting again, nothing should change"); prevRoutingTable = routingTable; clusterState = ClusterState.builder(clusterState).build(); routingTable = strategy.reroute(clusterState).routingTable(); assertThat(routingTable == prevRoutingTable, equalTo(true)); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); logger.info("Marking the shard as started"); RoutingNodes routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards( clusterState, routingNodes.node("node1").shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable != prevRoutingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node1")); logger.info("Starting another node and making sure nothing changed"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder(clusterState.nodes()).put(newNode("node2"))) .build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable == prevRoutingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node1")); logger.info("Killing node1 where the shard is, checking the shard is relocated"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder(clusterState.nodes()).remove("node1")) .build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable != prevRoutingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(INITIALIZING)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node2")); logger.info( "Start another node, make sure that things remain the same (shard is in node2 and initializing)"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder(clusterState.nodes()).put(newNode("node3"))) .build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable == prevRoutingTable, equalTo(true)); logger.info("Start the shard on node 2"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards( clusterState, routingNodes.node("node2").shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(routingTable != prevRoutingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).shards().get(0).currentNodeId(), equalTo("node2")); }
@Test public void testMultiIndexUnevenNodes() { AllocationService strategy = createAllocationService( settingsBuilder() .put("cluster.routing.allocation.concurrent_recoveries", 10) .put( ClusterRebalanceAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE, "always") .put("cluster.routing.allocation.cluster_concurrent_rebalance", -1) .build()); final int numberOfIndices = 10; logger.info("Building initial routing table with " + numberOfIndices + " indices"); MetaData.Builder metaDataBuilder = MetaData.builder(); for (int i = 0; i < numberOfIndices; i++) { metaDataBuilder.put( IndexMetaData.builder("test" + i) .settings(settings(Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(0)); } MetaData metaData = metaDataBuilder.build(); RoutingTable.Builder routingTableBuilder = RoutingTable.builder(); for (int i = 0; i < numberOfIndices; i++) { routingTableBuilder.addAsNew(metaData.index("test" + i)); } RoutingTable routingTable = routingTableBuilder.build(); ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT) .metaData(metaData) .routingTable(routingTable) .build(); assertThat(routingTable.indicesRouting().size(), equalTo(numberOfIndices)); logger.info("Starting 3 nodes and rerouting"); clusterState = ClusterState.builder(clusterState) .nodes( DiscoveryNodes.builder() .put(newNode("node1")) .put(newNode("node2")) .put(newNode("node3"))) .build(); RoutingTable prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), equalTo(INITIALIZING)); } RoutingNodes routingNodes = clusterState.routingNodes(); assertThat(numberOfShardsOfType(routingNodes, INITIALIZING), equalTo(numberOfIndices)); assertThat( routingNodes.node("node1").numberOfShardsWithState(INITIALIZING), anyOf(equalTo(3), equalTo(4))); assertThat( routingNodes.node("node2").numberOfShardsWithState(INITIALIZING), anyOf(equalTo(3), equalTo(4))); assertThat( routingNodes.node("node2").numberOfShardsWithState(INITIALIZING), anyOf(equalTo(3), equalTo(4))); logger.info("Start two more nodes, things should remain the same"); clusterState = ClusterState.builder(clusterState) .nodes( DiscoveryNodes.builder(clusterState.nodes()) .put(newNode("node4")) .put(newNode("node5"))) .build(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); assertThat(prevRoutingTable == routingTable, equalTo(true)); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), anyOf(equalTo(RELOCATING), equalTo(STARTED))); } routingNodes = clusterState.routingNodes(); assertThat( "4 source shard routing are relocating", numberOfShardsOfType(routingNodes, RELOCATING), equalTo(4)); assertThat( "4 target shard routing are initializing", numberOfShardsOfType(routingNodes, INITIALIZING), equalTo(4)); logger.info("Now, mark the relocated as started"); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); // routingTable = strategy.reroute(new RoutingStrategyInfo(metaData, routingTable), // nodes); assertThat(prevRoutingTable != routingTable, equalTo(true)); for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), anyOf(equalTo(RELOCATING), equalTo(STARTED))); } routingNodes = clusterState.routingNodes(); assertThat(numberOfShardsOfType(routingNodes, STARTED), equalTo(numberOfIndices)); for (RoutingNode routingNode : routingNodes) { assertThat(routingNode.numberOfShardsWithState(STARTED), equalTo(2)); } }
@Test public void testMultiIndexEvenDistribution() { AllocationService strategy = createAllocationService( settingsBuilder() .put("cluster.routing.allocation.concurrent_recoveries", 10) .put( ClusterRebalanceAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE, "always") .put("cluster.routing.allocation.cluster_concurrent_rebalance", -1) .build()); final int numberOfIndices = 50; logger.info("Building initial routing table with " + numberOfIndices + " indices"); MetaData.Builder metaDataBuilder = MetaData.builder(); for (int i = 0; i < numberOfIndices; i++) { metaDataBuilder.put( IndexMetaData.builder("test" + i) .settings(settings(Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(0)); } MetaData metaData = metaDataBuilder.build(); RoutingTable.Builder routingTableBuilder = RoutingTable.builder(); for (int i = 0; i < numberOfIndices; i++) { routingTableBuilder.addAsNew(metaData.index("test" + i)); } RoutingTable routingTable = routingTableBuilder.build(); ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT) .metaData(metaData) .routingTable(routingTable) .build(); assertThat(routingTable.indicesRouting().size(), equalTo(numberOfIndices)); for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).currentNodeId(), nullValue()); } logger.info("Adding " + (numberOfIndices / 2) + " nodes"); DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(); List<DiscoveryNode> nodes = newArrayList(); for (int i = 0; i < (numberOfIndices / 2); i++) { nodesBuilder.put(newNode("node" + i)); } RoutingTable prevRoutingTable = routingTable; clusterState = ClusterState.builder(clusterState).nodes(nodesBuilder).build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).unassigned(), equalTo(false)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), equalTo(INITIALIZING)); assertThat(routingTable.index("test" + i).shard(0).shards().get(0).primary(), equalTo(true)); // make sure we still have 2 shards initializing per node on the first 25 nodes String nodeId = routingTable.index("test" + i).shard(0).shards().get(0).currentNodeId(); int nodeIndex = Integer.parseInt(nodeId.substring("node".length())); assertThat(nodeIndex, lessThan(25)); } RoutingNodes routingNodes = clusterState.routingNodes(); Set<String> encounteredIndices = newHashSet(); for (RoutingNode routingNode : routingNodes) { assertThat(routingNode.numberOfShardsWithState(STARTED), equalTo(0)); assertThat(routingNode.size(), equalTo(2)); // make sure we still have 2 shards initializing per node on the only 25 nodes int nodeIndex = Integer.parseInt(routingNode.nodeId().substring("node".length())); assertThat(nodeIndex, lessThan(25)); // check that we don't have a shard associated with a node with the same index name (we have a // single shard) for (ShardRouting shardRoutingEntry : routingNode) { assertThat(encounteredIndices, not(hasItem(shardRoutingEntry.index()))); encounteredIndices.add(shardRoutingEntry.index()); } } logger.info("Adding additional " + (numberOfIndices / 2) + " nodes, nothing should change"); nodesBuilder = DiscoveryNodes.builder(clusterState.nodes()); for (int i = (numberOfIndices / 2); i < numberOfIndices; i++) { nodesBuilder.put(newNode("node" + i)); } prevRoutingTable = routingTable; clusterState = ClusterState.builder(clusterState).nodes(nodesBuilder).build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(false)); logger.info("Marking the shard as started"); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); int numberOfRelocatingShards = 0; int numberOfStartedShards = 0; for (int i = 0; i < numberOfIndices; i++) { assertThat(routingTable.index("test" + i).shards().size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).size(), equalTo(1)); assertThat(routingTable.index("test" + i).shard(0).shards().size(), equalTo(1)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).unassigned(), equalTo(false)); assertThat( routingTable.index("test" + i).shard(0).shards().get(0).state(), anyOf(equalTo(STARTED), equalTo(RELOCATING))); if (routingTable.index("test" + i).shard(0).shards().get(0).state() == STARTED) { numberOfStartedShards++; } else if (routingTable.index("test" + i).shard(0).shards().get(0).state() == RELOCATING) { numberOfRelocatingShards++; } assertThat(routingTable.index("test" + i).shard(0).shards().get(0).primary(), equalTo(true)); // make sure we still have 2 shards either relocating or started on the first 25 nodes (still) String nodeId = routingTable.index("test" + i).shard(0).shards().get(0).currentNodeId(); int nodeIndex = Integer.parseInt(nodeId.substring("node".length())); assertThat(nodeIndex, lessThan(25)); } assertThat(numberOfRelocatingShards, equalTo(25)); assertThat(numberOfStartedShards, equalTo(25)); }
@Test public void testUpdateNumberOfReplicas() { AllocationService strategy = createAllocationService( settingsBuilder().put("cluster.routing.allocation.concurrent_recoveries", 10).build()); logger.info("Building initial routing table"); MetaData metaData = MetaData.builder() .put(IndexMetaData.builder("test").numberOfShards(1).numberOfReplicas(1)) .build(); RoutingTable routingTable = RoutingTable.builder().addAsNew(metaData.index("test")).build(); ClusterState clusterState = ClusterState.builder().metaData(metaData).routingTable(routingTable).build(); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(1).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(0).currentNodeId(), nullValue()); assertThat(routingTable.index("test").shard(0).shards().get(1).currentNodeId(), nullValue()); logger.info("Adding two nodes and performing rerouting"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder().put(newNode("node1")).put(newNode("node2"))) .build(); RoutingTable prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); logger.info("Start all the primary shards"); RoutingNodes routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); logger.info("Start all the replica shards"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); final String nodeHoldingPrimary = routingTable.index("test").shard(0).primaryShard().currentNodeId(); final String nodeHoldingReplica = routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(); assertThat(nodeHoldingPrimary, not(equalTo(nodeHoldingReplica))); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo(nodeHoldingPrimary)); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(1)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo(nodeHoldingReplica)); logger.info("add another replica"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = RoutingTable.builder(routingTable).updateNumberOfReplicas(2).build(); metaData = MetaData.builder(clusterState.metaData()).updateNumberOfReplicas(2).build(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).metaData(metaData).build(); assertThat(clusterState.metaData().index("test").numberOfReplicas(), equalTo(2)); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo(nodeHoldingPrimary)); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo(nodeHoldingReplica)); assertThat( routingTable.index("test").shard(0).replicaShards().get(1).state(), equalTo(UNASSIGNED)); logger.info("Add another node and start the added replica"); clusterState = ClusterState.builder(clusterState) .nodes(DiscoveryNodes.builder(clusterState.nodes()).put(newNode("node3"))) .build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo(nodeHoldingPrimary)); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(STARTED).size(), equalTo(1)); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(STARTED).get(0).currentNodeId(), equalTo(nodeHoldingReplica)); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(INITIALIZING).size(), equalTo(1)); assertThat( routingTable .index("test") .shard(0) .replicaShardsWithState(INITIALIZING) .get(0) .currentNodeId(), equalTo("node3")); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo(nodeHoldingPrimary)); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(STARTED).size(), equalTo(2)); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(STARTED).get(0).currentNodeId(), anyOf(equalTo(nodeHoldingReplica), equalTo("node3"))); assertThat( routingTable.index("test").shard(0).replicaShardsWithState(STARTED).get(1).currentNodeId(), anyOf(equalTo(nodeHoldingReplica), equalTo("node3"))); logger.info("now remove a replica"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = RoutingTable.builder(routingTable).updateNumberOfReplicas(1).build(); metaData = MetaData.builder(clusterState.metaData()).updateNumberOfReplicas(1).build(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).metaData(metaData).build(); assertThat(clusterState.metaData().index("test").numberOfReplicas(), equalTo(1)); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo(nodeHoldingPrimary)); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(1)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat( routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), anyOf(equalTo(nodeHoldingReplica), equalTo("node3"))); logger.info("do a reroute, should remain the same"); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(false)); }
@Test public void testPrimaryRecoveryThrottling() { AllocationService strategy = new AllocationService( settingsBuilder() .put("cluster.routing.allocation.node_concurrent_recoveries", 3) .put("cluster.routing.allocation.node_initial_primaries_recoveries", 3) .build()); logger.info("Building initial routing table"); MetaData metaData = newMetaDataBuilder() .put(newIndexMetaDataBuilder("test").numberOfShards(10).numberOfReplicas(1)) .build(); RoutingTable routingTable = routingTable().addAsNew(metaData.index("test")).build(); ClusterState clusterState = newClusterStateBuilder().metaData(metaData).routingTable(routingTable).build(); logger.info("start one node, do reroute, only 3 should initialize"); clusterState = newClusterStateBuilder() .state(clusterState) .nodes(newNodesBuilder().put(newNode("node1"))) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(routingTable.shardsWithState(STARTED).size(), equalTo(0)); assertThat(routingTable.shardsWithState(INITIALIZING).size(), equalTo(3)); assertThat(routingTable.shardsWithState(UNASSIGNED).size(), equalTo(17)); logger.info("start initializing, another 3 should initialize"); routingTable = strategy .applyStartedShards(clusterState, routingTable.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(routingTable.shardsWithState(STARTED).size(), equalTo(3)); assertThat(routingTable.shardsWithState(INITIALIZING).size(), equalTo(3)); assertThat(routingTable.shardsWithState(UNASSIGNED).size(), equalTo(14)); logger.info("start initializing, another 3 should initialize"); routingTable = strategy .applyStartedShards(clusterState, routingTable.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(routingTable.shardsWithState(STARTED).size(), equalTo(6)); assertThat(routingTable.shardsWithState(INITIALIZING).size(), equalTo(3)); assertThat(routingTable.shardsWithState(UNASSIGNED).size(), equalTo(11)); logger.info("start initializing, another 1 should initialize"); routingTable = strategy .applyStartedShards(clusterState, routingTable.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(routingTable.shardsWithState(STARTED).size(), equalTo(9)); assertThat(routingTable.shardsWithState(INITIALIZING).size(), equalTo(1)); assertThat(routingTable.shardsWithState(UNASSIGNED).size(), equalTo(10)); logger.info("start initializing, all primaries should be started"); routingTable = strategy .applyStartedShards(clusterState, routingTable.shardsWithState(INITIALIZING)) .routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(routingTable.shardsWithState(STARTED).size(), equalTo(10)); assertThat(routingTable.shardsWithState(INITIALIZING).size(), equalTo(0)); assertThat(routingTable.shardsWithState(UNASSIGNED).size(), equalTo(10)); }