use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.
the class BalanceConfigurationTests method testNoRebalanceOnPrimaryOverload.
public void testNoRebalanceOnPrimaryOverload() {
Settings.Builder settings = Settings.builder();
AllocationService strategy = new AllocationService(settings.build(), randomAllocationDeciders(settings.build(), new ClusterSettings(Settings.Builder.EMPTY_SETTINGS, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), random()), new TestGatewayAllocator(), new ShardsAllocator() {
/*
* // 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
*/
public void allocate(RoutingAllocation allocation) {
RoutingNodes.UnassignedShards unassigned = allocation.routingNodes().unassigned();
ShardRouting[] drain = unassigned.drain();
// we have to allocate primaries first
ArrayUtil.timSort(drain, (a, b) -> {
return a.primary() ? -1 : 1;
});
for (ShardRouting sr : drain) {
switch(sr.id()) {
case 0:
if (sr.primary()) {
allocation.routingNodes().initializeShard(sr, "node1", null, -1, allocation.changes());
} else {
allocation.routingNodes().initializeShard(sr, "node0", null, -1, allocation.changes());
}
break;
case 1:
if (sr.primary()) {
allocation.routingNodes().initializeShard(sr, "node1", null, -1, allocation.changes());
} else {
allocation.routingNodes().initializeShard(sr, "node2", null, -1, allocation.changes());
}
break;
case 2:
if (sr.primary()) {
allocation.routingNodes().initializeShard(sr, "node3", null, -1, allocation.changes());
} else {
allocation.routingNodes().initializeShard(sr, "node2", null, -1, allocation.changes());
}
break;
case 3:
if (sr.primary()) {
allocation.routingNodes().initializeShard(sr, "node3", null, -1, allocation.changes());
} else {
allocation.routingNodes().initializeShard(sr, "node1", null, -1, allocation.changes());
}
break;
case 4:
if (sr.primary()) {
allocation.routingNodes().initializeShard(sr, "node2", null, -1, allocation.changes());
} else {
allocation.routingNodes().initializeShard(sr, "node0", null, -1, allocation.changes());
}
break;
}
}
}
@Override
public ShardAllocationDecision decideShardAllocation(ShardRouting shard, RoutingAllocation allocation) {
throw new UnsupportedOperationException("explain not supported");
}
}, 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.add(node);
}
ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)).nodes(nodes).metaData(metaData).routingTable(routingTable).build();
routingTable = strategy.reroute(clusterState, "reroute").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(), new NoopGatewayAllocator());
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, "reroute").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));
}
}
}
use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.
the class BalanceConfigurationTests method testReplicaBalance.
public void testReplicaBalance() {
/* Tests balance over replicas only */
final float indexBalance = 0.0f;
final float replicaBalance = 1.0f;
final float balanceTreshold = 1.0f;
Settings.Builder settings = Settings.builder();
settings.put(ClusterRebalanceAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING.getKey(), ClusterRebalanceAllocationDecider.ClusterRebalanceType.ALWAYS.toString());
settings.put(BalancedShardsAllocator.INDEX_BALANCE_FACTOR_SETTING.getKey(), indexBalance);
settings.put(BalancedShardsAllocator.SHARD_BALANCE_FACTOR_SETTING.getKey(), replicaBalance);
settings.put(BalancedShardsAllocator.THRESHOLD_SETTING.getKey(), balanceTreshold);
AllocationService strategy = createAllocationService(settings.build(), new NoopGatewayAllocator());
ClusterState clusterState = initCluster(strategy);
assertReplicaBalance(logger, clusterState.getRoutingNodes(), numberOfNodes, numberOfIndices, numberOfReplicas, numberOfShards, balanceTreshold);
clusterState = addNode(clusterState, strategy);
assertReplicaBalance(logger, clusterState.getRoutingNodes(), numberOfNodes + 1, numberOfIndices, numberOfReplicas, numberOfShards, balanceTreshold);
clusterState = removeNodes(clusterState, strategy);
assertReplicaBalance(logger, clusterState.getRoutingNodes(), (numberOfNodes + 1) - (numberOfNodes + 1) / 2, numberOfIndices, numberOfReplicas, numberOfShards, balanceTreshold);
}
use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.
the class BalanceUnbalancedClusterTests method allocateNew.
@Override
protected ClusterState allocateNew(ClusterState state) {
String index = "tweets-2014-12-29:00";
AllocationService strategy = createAllocationService(Settings.builder().build());
MetaData metaData = MetaData.builder(state.metaData()).put(IndexMetaData.builder(index).settings(settings(Version.CURRENT)).numberOfShards(5).numberOfReplicas(1)).build();
RoutingTable initialRoutingTable = RoutingTable.builder(state.routingTable()).addAsNew(metaData.index(index)).build();
ClusterState clusterState = ClusterState.builder(state).metaData(metaData).routingTable(initialRoutingTable).build();
clusterState = strategy.reroute(clusterState, "reroute");
while (true) {
if (clusterState.routingTable().shardsWithState(INITIALIZING).isEmpty()) {
break;
}
clusterState = strategy.applyStartedShards(clusterState, clusterState.routingTable().shardsWithState(INITIALIZING));
}
Map<String, Integer> counts = new HashMap<>();
for (IndexShardRoutingTable table : clusterState.routingTable().index(index)) {
for (ShardRouting r : table) {
String s = r.currentNodeId();
Integer count = counts.get(s);
if (count == null) {
count = 0;
}
count++;
counts.put(s, count);
}
}
for (Map.Entry<String, Integer> count : counts.entrySet()) {
// we have 10 shards and 4 nodes so 2 nodes have 3 shards and 2 nodes have 2 shards
assertTrue("Node: " + count.getKey() + " has shard mismatch: " + count.getValue(), count.getValue() >= 2);
assertTrue("Node: " + count.getKey() + " has shard mismatch: " + count.getValue(), count.getValue() <= 3);
}
return clusterState;
}
use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.
the class BalancedSingleShardTests method testNodeDecisionsRanking.
public void testNodeDecisionsRanking() {
// only one shard, so moving it will not create a better balance anywhere, so all node decisions should
// return the same ranking as the current node
ClusterState clusterState = ClusterStateCreationUtils.state(randomIntBetween(1, 10), new String[] { "idx" }, 1);
ShardRouting shardToRebalance = clusterState.routingTable().index("idx").shardsWithState(ShardRoutingState.STARTED).get(0);
MoveDecision decision = executeRebalanceFor(shardToRebalance, clusterState, emptySet(), -1);
int currentRanking = decision.getCurrentNodeRanking();
assertEquals(1, currentRanking);
for (NodeAllocationResult result : decision.getNodeDecisions()) {
assertEquals(1, result.getWeightRanking());
}
// start off with one node and several shards assigned to that node, then add a few nodes to the cluster,
// each of these new nodes should have a better ranking than the current, given a low enough threshold
clusterState = ClusterStateCreationUtils.state(1, new String[] { "idx" }, randomIntBetween(2, 10));
shardToRebalance = clusterState.routingTable().index("idx").shardsWithState(ShardRoutingState.STARTED).get(0);
clusterState = addNodesToClusterState(clusterState, randomIntBetween(1, 10));
decision = executeRebalanceFor(shardToRebalance, clusterState, emptySet(), 0.01f);
for (NodeAllocationResult result : decision.getNodeDecisions()) {
assertThat(result.getWeightRanking(), lessThan(decision.getCurrentNodeRanking()));
}
// start off with 3 nodes and 7 shards, so that one of the 3 nodes will have 3 shards assigned, the remaining 2
// nodes will have 2 shard each. then, add another node. pick a shard on one of the nodes that has only 2 shard
// to rebalance. the new node should have the best ranking (because it has no shards), followed by the node currently
// holding the shard as well as the other node with only 2 shards (they should have the same ranking), followed by the
// node with 3 shards which will have the lowest ranking.
clusterState = ClusterStateCreationUtils.state(3, new String[] { "idx" }, 7);
shardToRebalance = null;
Set<String> nodesWithTwoShards = new HashSet<>();
String nodeWithThreeShards = null;
for (RoutingNode node : clusterState.getRoutingNodes()) {
if (node.numberOfShardsWithState(ShardRoutingState.STARTED) == 2) {
nodesWithTwoShards.add(node.nodeId());
if (shardToRebalance == null) {
shardToRebalance = node.shardsWithState(ShardRoutingState.STARTED).get(0);
}
} else {
assertEquals(3, node.numberOfShardsWithState(ShardRoutingState.STARTED));
// should only have one of these
assertNull(nodeWithThreeShards);
nodeWithThreeShards = node.nodeId();
}
}
clusterState = addNodesToClusterState(clusterState, 1);
decision = executeRebalanceFor(shardToRebalance, clusterState, emptySet(), 0.01f);
for (NodeAllocationResult result : decision.getNodeDecisions()) {
if (result.getWeightRanking() < decision.getCurrentNodeRanking()) {
// highest ranked node should not be any of the initial nodes
assertFalse(nodesWithTwoShards.contains(result.getNode().getId()));
assertNotEquals(nodeWithThreeShards, result.getNode().getId());
} else if (result.getWeightRanking() > decision.getCurrentNodeRanking()) {
// worst ranked should be the node with two shards
assertEquals(nodeWithThreeShards, result.getNode().getId());
} else {
assertTrue(nodesWithTwoShards.contains(result.getNode().getId()));
}
}
}
use of org.elasticsearch.cluster.ClusterState in project elasticsearch by elastic.
the class BalancedSingleShardTests method testRebalancePossible.
public void testRebalancePossible() {
AllocationDecider canAllocateDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
return Decision.YES;
}
};
Tuple<ClusterState, MoveDecision> rebalance = setupStateAndRebalance(canAllocateDecider, Settings.EMPTY, true);
ClusterState clusterState = rebalance.v1();
MoveDecision rebalanceDecision = rebalance.v2();
assertEquals(Type.YES, rebalanceDecision.getClusterRebalanceDecision().type());
assertNotNull(rebalanceDecision.getExplanation());
assertEquals(clusterState.nodes().getSize() - 1, rebalanceDecision.getNodeDecisions().size());
}
Aggregations