private ClusterState addNode(ClusterState clusterState, AllocationService strategy) { logger.info( "now, start 1 more node, check that rebalancing will happen because we set it to always"); clusterState = ClusterState.builder(clusterState) .nodes( DiscoveryNodes.builder(clusterState.nodes()).put(newNode("node" + numberOfNodes))) .build(); RoutingTable routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); RoutingNodes routingNodes = clusterState.getRoutingNodes(); // move initializing to started RoutingTable prev = routingTable; while (true) { routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); if (routingTable == prev) break; prev = routingTable; } return clusterState; }
@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()); }
private ClusterState removeNodes(ClusterState clusterState, AllocationService strategy) { logger.info("Removing half the nodes (" + (numberOfNodes + 1) / 2 + ")"); DiscoveryNodes.Builder nodes = DiscoveryNodes.builder(clusterState.nodes()); for (int i = (numberOfNodes + 1) / 2; i <= numberOfNodes; i++) { nodes.remove("node" + i); } clusterState = ClusterState.builder(clusterState).nodes(nodes.build()).build(); RoutingNodes routingNodes = clusterState.getRoutingNodes(); logger.info("start all the primary shards, replicas will start initializing"); RoutingTable routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); logger.info("start the replica shards"); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); logger.info("rebalancing"); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); logger.info("complete rebalancing"); RoutingTable prev = routingTable; while (true) { routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); if (routingTable == prev) break; prev = routingTable; } return clusterState; }
@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").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 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("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).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().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("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).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().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 (MutableShardRouting 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 tesStartedShardsMatching() { AllocationService allocation = createAllocationService(); logger.info("--> building initial cluster state"); final IndexMetaData indexMetaData = IndexMetaData.builder("test").numberOfShards(3).numberOfReplicas(0).build(); ClusterState.Builder stateBuilder = ClusterState.builder(ClusterName.DEFAULT) .nodes(DiscoveryNodes.builder().put(newNode("node1")).put(newNode("node2"))) .metaData(MetaData.builder().put(indexMetaData, false)); final ImmutableShardRouting initShard = new ImmutableShardRouting( "test", 0, "node1", randomBoolean(), ShardRoutingState.INITIALIZING, 1); final ImmutableShardRouting startedShard = new ImmutableShardRouting( "test", 1, "node2", randomBoolean(), ShardRoutingState.STARTED, 1); final ImmutableShardRouting relocatingShard = new ImmutableShardRouting( "test", 2, "node1", "node2", randomBoolean(), ShardRoutingState.RELOCATING, 1); stateBuilder.routingTable( RoutingTable.builder() .add( IndexRoutingTable.builder("test") .addIndexShard( new IndexShardRoutingTable.Builder(initShard.shardId(), true) .addShard(initShard) .build()) .addIndexShard( new IndexShardRoutingTable.Builder(startedShard.shardId(), true) .addShard(startedShard) .build()) .addIndexShard( new IndexShardRoutingTable.Builder(relocatingShard.shardId(), true) .addShard(relocatingShard) .build()))); ClusterState state = stateBuilder.build(); logger.info("--> test starting of shard"); RoutingAllocation.Result result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( initShard.index(), initShard.id(), initShard.currentNodeId(), initShard.relocatingNodeId(), initShard.primary(), ShardRoutingState.INITIALIZING, randomInt())), false); assertTrue( "failed to start " + initShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); assertTrue( initShard + "isn't started \ncurrent routing table:" + result.routingTable().prettyPrint(), result .routingTable() .index("test") .shard(initShard.id()) .countWithState(ShardRoutingState.STARTED) == 1); logger.info("--> testing shard variants that shouldn't match the started shard"); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( initShard.index(), initShard.id(), initShard.currentNodeId(), initShard.relocatingNodeId(), !initShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "wrong primary flag shouldn't start shard " + initShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( initShard.index(), initShard.id(), "some_node", initShard.currentNodeId(), initShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "relocating shard from node shouldn't start shard " + initShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( initShard.index(), initShard.id(), initShard.currentNodeId(), "some_node", initShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "relocating shard to node shouldn't start shard " + initShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); logger.info("--> testing double starting"); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( startedShard.index(), startedShard.id(), startedShard.currentNodeId(), startedShard.relocatingNodeId(), startedShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "duplicate starting of the same shard should be ignored \ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); logger.info("--> testing starting of relocating shards"); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( relocatingShard.index(), relocatingShard.id(), relocatingShard.relocatingNodeId(), relocatingShard.currentNodeId(), relocatingShard.primary(), ShardRoutingState.INITIALIZING, randomInt())), false); assertTrue( "failed to start " + relocatingShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); ShardRouting shardRouting = result.routingTable().index("test").shard(relocatingShard.id()).getShards().get(0); assertThat(shardRouting.state(), equalTo(ShardRoutingState.STARTED)); assertThat(shardRouting.currentNodeId(), equalTo("node2")); assertThat(shardRouting.relocatingNodeId(), nullValue()); logger.info("--> testing shard variants that shouldn't match the relocating shard"); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( relocatingShard.index(), relocatingShard.id(), relocatingShard.relocatingNodeId(), relocatingShard.currentNodeId(), !relocatingShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "wrong primary flag shouldn't start shard " + relocatingShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( relocatingShard.index(), relocatingShard.id(), "some_node", relocatingShard.currentNodeId(), relocatingShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "relocating shard to a different node shouldn't start shard " + relocatingShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( relocatingShard.index(), relocatingShard.id(), relocatingShard.relocatingNodeId(), "some_node", relocatingShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "relocating shard from a different node shouldn't start shard " + relocatingShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); result = allocation.applyStartedShards( state, Arrays.asList( new ImmutableShardRouting( relocatingShard.index(), relocatingShard.id(), relocatingShard.relocatingNodeId(), relocatingShard.primary(), ShardRoutingState.INITIALIZING, 1)), false); assertFalse( "non-relocating shard shouldn't start shard" + relocatingShard + "\ncurrent routing table:" + result.routingTable().prettyPrint(), result.changed()); }
@Test public void testNoRebalanceOnPrimaryOverload() { Settings.Builder settings = settingsBuilder(); AllocationService strategy = new AllocationService( settings.build(), randomAllocationDeciders( settings.build(), new NodeSettingsService(Settings.Builder.EMPTY_SETTINGS), getRandom()), new ShardsAllocators( settings.build(), NoopGatewayAllocator.INSTANCE, new ShardsAllocator() { @Override public boolean rebalance(RoutingAllocation allocation) { return false; } @Override public boolean move( ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) { return false; } @Override public void applyStartedShards(StartedRerouteAllocation allocation) {} @Override public void applyFailedShards(FailedRerouteAllocation allocation) {} /* * // this allocator tries to rebuild this scenario where a rebalance is * // triggered solely by the primary overload on node [1] where a shard * // is rebalanced to node 0 routing_nodes: -----node_id[0][V] --------[test][0], node[0], [R], s[STARTED] --------[test][4], node[0], [R], s[STARTED] -----node_id[1][V] --------[test][0], node[1], [P], s[STARTED] --------[test][1], node[1], [P], s[STARTED] --------[test][3], node[1], [R], s[STARTED] -----node_id[2][V] --------[test][1], node[2], [R], s[STARTED] --------[test][2], node[2], [R], s[STARTED] --------[test][4], node[2], [P], s[STARTED] -----node_id[3][V] --------[test][2], node[3], [P], s[STARTED] --------[test][3], node[3], [P], s[STARTED] ---- unassigned */ @Override public boolean allocateUnassigned(RoutingAllocation allocation) { RoutingNodes.UnassignedShards unassigned = allocation.routingNodes().unassigned(); boolean changed = !unassigned.isEmpty(); for (ShardRouting sr : unassigned) { switch (sr.id()) { case 0: if (sr.primary()) { allocation.routingNodes().initialize(sr, "node1"); } else { allocation.routingNodes().initialize(sr, "node0"); } break; case 1: if (sr.primary()) { allocation.routingNodes().initialize(sr, "node1"); } else { allocation.routingNodes().initialize(sr, "node2"); } break; case 2: if (sr.primary()) { allocation.routingNodes().initialize(sr, "node3"); } else { allocation.routingNodes().initialize(sr, "node2"); } break; case 3: if (sr.primary()) { allocation.routingNodes().initialize(sr, "node3"); } else { allocation.routingNodes().initialize(sr, "node1"); } break; case 4: if (sr.primary()) { allocation.routingNodes().initialize(sr, "node2"); } else { allocation.routingNodes().initialize(sr, "node0"); } break; } } unassigned.clear(); return changed; } }), EmptyClusterInfoService.INSTANCE); MetaData.Builder metaDataBuilder = MetaData.builder(); RoutingTable.Builder routingTableBuilder = RoutingTable.builder(); IndexMetaData.Builder indexMeta = IndexMetaData.builder("test") .settings(settings(Version.CURRENT)) .numberOfShards(5) .numberOfReplicas(1); metaDataBuilder = metaDataBuilder.put(indexMeta); MetaData metaData = metaDataBuilder.build(); for (ObjectCursor<IndexMetaData> cursor : metaData.indices().values()) { routingTableBuilder.addAsNew(cursor.value); } RoutingTable routingTable = routingTableBuilder.build(); DiscoveryNodes.Builder nodes = DiscoveryNodes.builder(); for (int i = 0; i < 4; i++) { DiscoveryNode node = newNode("node" + i); nodes.put(node); } ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT) .nodes(nodes) .metaData(metaData) .routingTable(routingTable) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); RoutingNodes routingNodes = clusterState.getRoutingNodes(); for (RoutingNode routingNode : routingNodes) { for (ShardRouting shardRouting : routingNode) { assertThat(shardRouting.state(), Matchers.equalTo(ShardRoutingState.INITIALIZING)); } } strategy = createAllocationService(settings.build()); logger.info("use the new allocator and check if it moves shards"); routingNodes = clusterState.getRoutingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); for (RoutingNode routingNode : routingNodes) { for (ShardRouting shardRouting : routingNode) { assertThat(shardRouting.state(), Matchers.equalTo(ShardRoutingState.STARTED)); } } logger.info("start the replica shards"); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); for (RoutingNode routingNode : routingNodes) { for (ShardRouting shardRouting : routingNode) { assertThat(shardRouting.state(), Matchers.equalTo(ShardRoutingState.STARTED)); } } logger.info("rebalancing"); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); for (RoutingNode routingNode : routingNodes) { for (ShardRouting shardRouting : routingNode) { assertThat(shardRouting.state(), Matchers.equalTo(ShardRoutingState.STARTED)); } } }
private ClusterState initCluster(AllocationService strategy) { MetaData.Builder metaDataBuilder = MetaData.builder(); RoutingTable.Builder routingTableBuilder = RoutingTable.builder(); for (int i = 0; i < numberOfIndices; i++) { IndexMetaData.Builder index = IndexMetaData.builder("test" + i) .settings(settings(Version.CURRENT)) .numberOfShards(numberOfShards) .numberOfReplicas(numberOfReplicas); metaDataBuilder = metaDataBuilder.put(index); } MetaData metaData = metaDataBuilder.build(); for (ObjectCursor<IndexMetaData> cursor : metaData.indices().values()) { routingTableBuilder.addAsNew(cursor.value); } RoutingTable routingTable = routingTableBuilder.build(); logger.info("start " + numberOfNodes + " nodes"); DiscoveryNodes.Builder nodes = DiscoveryNodes.builder(); for (int i = 0; i < numberOfNodes; i++) { nodes.put(newNode("node" + i)); } ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT) .nodes(nodes) .metaData(metaData) .routingTable(routingTable) .build(); routingTable = strategy.reroute(clusterState).routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); RoutingNodes routingNodes = clusterState.getRoutingNodes(); logger.info("restart all the primary shards, replicas will start initializing"); routingNodes = clusterState.getRoutingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); logger.info("start the replica shards"); routingNodes = clusterState.getRoutingNodes(); routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); logger.info("complete rebalancing"); RoutingTable prev = routingTable; while (true) { routingTable = strategy .applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)) .routingTable(); clusterState = ClusterState.builder(clusterState).routingTable(routingTable).build(); routingNodes = clusterState.getRoutingNodes(); if (routingTable == prev) break; prev = routingTable; } return clusterState; }