use of org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider in project elasticsearch by elastic.
the class BalancedSingleShardTests method setupStateAndRebalance.
private Tuple<ClusterState, MoveDecision> setupStateAndRebalance(AllocationDecider allocationDecider, Settings balancerSettings, boolean rebalanceExpected) {
AllocationDecider rebalanceDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canRebalance(ShardRouting shardRouting, RoutingAllocation allocation) {
return Decision.YES;
}
};
List<AllocationDecider> allocationDeciders = Arrays.asList(rebalanceDecider, allocationDecider);
final int numShards = randomIntBetween(8, 13);
BalancedShardsAllocator allocator = new BalancedShardsAllocator(balancerSettings);
ClusterState clusterState = ClusterStateCreationUtils.state("idx", 2, numShards);
// add a new node so shards can be rebalanced there
DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterState.nodes());
nodesBuilder.add(newNode(randomAsciiOfLength(7)));
clusterState = ClusterState.builder(clusterState).nodes(nodesBuilder).build();
ShardRouting shard = clusterState.routingTable().index("idx").shard(0).primaryShard();
RoutingAllocation routingAllocation = newRoutingAllocation(new AllocationDeciders(Settings.EMPTY, allocationDeciders), clusterState);
MoveDecision rebalanceDecision = allocator.decideShardAllocation(shard, routingAllocation).getMoveDecision();
if (rebalanceExpected == false) {
assertAssignedNodeRemainsSame(allocator, routingAllocation, shard);
}
return Tuple.tuple(clusterState, rebalanceDecision);
}
use of org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider in project elasticsearch by elastic.
the class BalancedSingleShardTests method testRebalancingNotAllowedDueToCanRebalance.
public void testRebalancingNotAllowedDueToCanRebalance() {
final Decision canRebalanceDecision = randomFrom(Decision.NO, Decision.THROTTLE);
AllocationDecider noRebalanceDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canRebalance(ShardRouting shardRouting, RoutingAllocation allocation) {
return allocation.decision(canRebalanceDecision, "TEST", "foobar");
}
};
BalancedShardsAllocator allocator = new BalancedShardsAllocator(Settings.EMPTY);
ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), ShardRoutingState.STARTED);
ShardRouting shard = clusterState.routingTable().index("idx").shard(0).primaryShard();
RoutingAllocation routingAllocation = newRoutingAllocation(new AllocationDeciders(Settings.EMPTY, Collections.singleton(noRebalanceDecider)), clusterState);
MoveDecision rebalanceDecision = allocator.decideShardAllocation(shard, routingAllocation).getMoveDecision();
assertEquals(canRebalanceDecision.type(), rebalanceDecision.getClusterRebalanceDecision().type());
assertEquals(AllocationDecision.fromDecisionType(canRebalanceDecision.type()), rebalanceDecision.getAllocationDecision());
assertThat(rebalanceDecision.getExplanation(), containsString(canRebalanceDecision.type() == Type.THROTTLE ? "rebalancing is throttled" : "rebalancing is not allowed"));
assertNotNull(rebalanceDecision.getNodeDecisions());
assertNull(rebalanceDecision.getTargetNode());
assertEquals(1, rebalanceDecision.getClusterRebalanceDecision().getDecisions().size());
for (Decision subDecision : rebalanceDecision.getClusterRebalanceDecision().getDecisions()) {
assertEquals("foobar", ((Decision.Single) subDecision).getExplanation());
}
assertAssignedNodeRemainsSame(allocator, routingAllocation, shard);
}
use of org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider in project elasticsearch by elastic.
the class BalancedSingleShardTests method testRebalancingNotAllowedDueToCanAllocate.
public void testRebalancingNotAllowedDueToCanAllocate() {
AllocationDecider canAllocateDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
return Decision.NO;
}
};
Tuple<ClusterState, MoveDecision> rebalance = setupStateAndRebalance(canAllocateDecider, Settings.EMPTY, false);
ClusterState clusterState = rebalance.v1();
MoveDecision rebalanceDecision = rebalance.v2();
assertEquals(Type.YES, rebalanceDecision.getClusterRebalanceDecision().type());
assertEquals(AllocationDecision.NO, rebalanceDecision.getAllocationDecision());
assertThat(rebalanceDecision.getExplanation(), startsWith("cannot rebalance as no target node exists that can both allocate this shard and improve the cluster balance"));
assertEquals(clusterState.nodes().getSize() - 1, rebalanceDecision.getNodeDecisions().size());
assertNull(rebalanceDecision.getTargetNode());
int prevRanking = 0;
for (NodeAllocationResult result : rebalanceDecision.getNodeDecisions()) {
assertThat(result.getWeightRanking(), greaterThanOrEqualTo(prevRanking));
prevRanking = result.getWeightRanking();
}
}
use of org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider in project elasticsearch by elastic.
the class BalancedSingleShardTests method testSingleShardBalanceProducesSameResultsAsBalanceStep.
public void testSingleShardBalanceProducesSameResultsAsBalanceStep() {
final String[] indices = { "idx1", "idx2" };
// Create a cluster state with 2 indices, each with 1 started primary shard, and only
// one node initially so that all primary shards get allocated to the same node. We are only
// using 2 indices (i.e. 2 total primary shards) because if we have any more than 2 started shards
// in the routing table, then we have no guarantees about the order in which the 3 or more shards
// are selected to be rebalanced to the new node, and hence the node to which they are rebalanced
// is not deterministic. Using only two shards guarantees that only one of those two shards will
// be rebalanced, and so we pick the one that was chosen to be rebalanced and execute the single-shard
// rebalance step on it to make sure it gets assigned to the same node.
ClusterState clusterState = ClusterStateCreationUtils.state(1, indices, 1);
// add new nodes so one of the primaries can be rebalanced
DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterState.nodes());
int numAddedNodes = randomIntBetween(1, 5);
// randomly select a subset of the newly added nodes to set filter allocation on (but not all)
int excludeNodesSize = randomIntBetween(0, numAddedNodes - 1);
final Set<String> excludeNodes = new HashSet<>();
for (int i = 0; i < numAddedNodes; i++) {
DiscoveryNode discoveryNode = newNode(randomAsciiOfLength(7));
nodesBuilder.add(discoveryNode);
if (i < excludeNodesSize) {
excludeNodes.add(discoveryNode.getId());
}
}
clusterState = ClusterState.builder(clusterState).nodes(nodesBuilder).build();
AllocationDecider allocationDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
if (excludeNodes.contains(node.nodeId())) {
return Decision.NO;
}
return Decision.YES;
}
};
AllocationDecider rebalanceDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canRebalance(ShardRouting shardRouting, RoutingAllocation allocation) {
return Decision.YES;
}
};
List<AllocationDecider> allocationDeciders = Arrays.asList(rebalanceDecider, allocationDecider);
RoutingAllocation routingAllocation = newRoutingAllocation(new AllocationDeciders(Settings.EMPTY, allocationDeciders), clusterState);
// allocate and get the node that is now relocating
BalancedShardsAllocator allocator = new BalancedShardsAllocator(Settings.EMPTY);
allocator.allocate(routingAllocation);
ShardRouting shardToRebalance = null;
for (RoutingNode routingNode : routingAllocation.routingNodes()) {
List<ShardRouting> relocatingShards = routingNode.shardsWithState(ShardRoutingState.RELOCATING);
if (relocatingShards.size() > 0) {
shardToRebalance = randomFrom(relocatingShards);
break;
}
}
routingAllocation = newRoutingAllocation(new AllocationDeciders(Settings.EMPTY, allocationDeciders), clusterState);
routingAllocation.debugDecision(true);
ShardRouting shard = clusterState.getRoutingNodes().activePrimary(shardToRebalance.shardId());
MoveDecision rebalanceDecision = allocator.decideShardAllocation(shard, routingAllocation).getMoveDecision();
assertEquals(shardToRebalance.relocatingNodeId(), rebalanceDecision.getTargetNode().getId());
// make sure all excluded nodes returned a NO decision
for (NodeAllocationResult nodeResult : rebalanceDecision.getNodeDecisions()) {
if (excludeNodes.contains(nodeResult.getNode().getId())) {
assertEquals(Type.NO, nodeResult.getCanAllocateDecision().type());
}
}
}
use of org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider in project elasticsearch by elastic.
the class DecisionsImpactOnClusterHealthTests method testPrimaryShardYesDecisionOnIndexCreation.
public void testPrimaryShardYesDecisionOnIndexCreation() throws IOException {
final String indexName = "test-idx";
Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toAbsolutePath().toString()).build();
AllocationDecider decider = new TestAllocateDecision(Decision.YES) {
@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
if (node.getByShardId(shardRouting.shardId()) == null) {
return Decision.YES;
} else {
return Decision.NO;
}
}
};
// if deciders say YES to allocating primary shards, stay in YELLOW state
ClusterState clusterState = runAllocationTest(settings, indexName, Collections.singleton(decider), ClusterHealthStatus.YELLOW);
// make sure primaries are initialized
RoutingTable routingTable = clusterState.routingTable();
for (IndexShardRoutingTable indexShardRoutingTable : routingTable.index(indexName)) {
assertTrue(indexShardRoutingTable.primaryShard().initializing());
}
}
Aggregations