use of org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision in project elasticsearch by elastic.
the class ClusterAllocationExplainIT method testAllocationFilteringPreventsShardMove.
public void testAllocationFilteringPreventsShardMove() throws Exception {
logger.info("--> starting 2 nodes");
internalCluster().startNodes(2);
logger.info("--> creating an index with 1 primary and 0 replicas");
createIndexAndIndexData(1, 0);
logger.info("--> setting up allocation filtering to prevent allocation to both nodes");
client().admin().indices().prepareUpdateSettings("idx").setSettings(Settings.builder().put("index.routing.allocation.include._name", "non_existent_node")).get();
boolean includeYesDecisions = randomBoolean();
boolean includeDiskInfo = randomBoolean();
ClusterAllocationExplanation explanation = runExplain(true, includeYesDecisions, includeDiskInfo);
ShardId shardId = explanation.getShard();
boolean isPrimary = explanation.isPrimary();
ShardRoutingState shardRoutingState = explanation.getShardState();
DiscoveryNode currentNode = explanation.getCurrentNode();
UnassignedInfo unassignedInfo = explanation.getUnassignedInfo();
ClusterInfo clusterInfo = explanation.getClusterInfo();
AllocateUnassignedDecision allocateDecision = explanation.getShardAllocationDecision().getAllocateDecision();
MoveDecision moveDecision = explanation.getShardAllocationDecision().getMoveDecision();
// verify shard info
assertEquals("idx", shardId.getIndexName());
assertEquals(0, shardId.getId());
assertTrue(isPrimary);
// verify current node info
assertEquals(ShardRoutingState.STARTED, shardRoutingState);
assertNotNull(currentNode);
// verify unassigned info
assertNull(unassignedInfo);
// verify cluster info
verifyClusterInfo(clusterInfo, includeDiskInfo, 2);
// verify decision object
assertFalse(allocateDecision.isDecisionTaken());
assertTrue(moveDecision.isDecisionTaken());
assertEquals(AllocationDecision.NO, moveDecision.getAllocationDecision());
assertEquals("cannot move shard to another node, even though it is not allowed to remain on its current node", moveDecision.getExplanation());
assertFalse(moveDecision.canRemain());
assertFalse(moveDecision.forceMove());
assertFalse(moveDecision.canRebalanceCluster());
assertNull(moveDecision.getClusterRebalanceDecision());
assertNull(moveDecision.getTargetNode());
assertEquals(0, moveDecision.getCurrentNodeRanking());
// verifying can remain decision object
assertNotNull(moveDecision.getCanRemainDecision());
assertEquals(Decision.Type.NO, moveDecision.getCanRemainDecision().type());
for (Decision d : moveDecision.getCanRemainDecision().getDecisions()) {
if (d.label().equals("filter")) {
assertEquals(Decision.Type.NO, d.type());
assertEquals("node does not match index setting [index.routing.allocation.include] filters [_name:\"non_existent_node\"]", d.getExplanation());
} else {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
}
// verify node decisions
assertEquals(1, moveDecision.getNodeDecisions().size());
NodeAllocationResult result = moveDecision.getNodeDecisions().get(0);
assertNotNull(result.getNode());
assertEquals(1, result.getWeightRanking());
assertEquals(AllocationDecision.NO, result.getNodeDecision());
if (includeYesDecisions) {
assertThat(result.getCanAllocateDecision().getDecisions().size(), greaterThan(1));
} else {
assertEquals(1, result.getCanAllocateDecision().getDecisions().size());
}
for (Decision d : result.getCanAllocateDecision().getDecisions()) {
if (d.label().equals("filter")) {
assertEquals(Decision.Type.NO, d.type());
assertEquals("node does not match index setting [index.routing.allocation.include] filters [_name:\"non_existent_node\"]", d.getExplanation());
} else {
assertEquals(Decision.Type.YES, d.type());
assertNotNull(d.getExplanation());
}
}
// verify JSON output
try (XContentParser parser = getParser(explanation)) {
verifyShardInfo(parser, true, includeDiskInfo, ShardRoutingState.STARTED);
parser.nextToken();
assertEquals("can_remain_on_current_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("can_remain_decisions", parser.currentName());
verifyDeciders(parser, AllocationDecision.NO);
parser.nextToken();
assertEquals("can_move_to_other_node", parser.currentName());
parser.nextToken();
assertEquals(AllocationDecision.NO.toString(), parser.text());
parser.nextToken();
assertEquals("move_explanation", parser.currentName());
parser.nextToken();
assertEquals("cannot move shard to another node, even though it is not allowed to remain on its current node", parser.text());
verifyNodeDecisions(parser, allNodeDecisions(AllocationDecision.NO, true), includeYesDecisions, false);
assertEquals(Token.END_OBJECT, parser.nextToken());
}
}
use of org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision in project elasticsearch by elastic.
the class BaseGatewayShardAllocator method allocateUnassigned.
/**
* Allocate unassigned shards to nodes (if any) where valid copies of the shard already exist.
* It is up to the individual implementations of {@link #makeAllocationDecision(ShardRouting, RoutingAllocation, Logger)}
* to make decisions on assigning shards to nodes.
*
* @param allocation the allocation state container object
*/
public void allocateUnassigned(RoutingAllocation allocation) {
final RoutingNodes routingNodes = allocation.routingNodes();
final RoutingNodes.UnassignedShards.UnassignedIterator unassignedIterator = routingNodes.unassigned().iterator();
while (unassignedIterator.hasNext()) {
final ShardRouting shard = unassignedIterator.next();
final AllocateUnassignedDecision allocateUnassignedDecision = makeAllocationDecision(shard, allocation, logger);
if (allocateUnassignedDecision.isDecisionTaken() == false) {
// no decision was taken by this allocator
continue;
}
if (allocateUnassignedDecision.getAllocationDecision() == AllocationDecision.YES) {
unassignedIterator.initialize(allocateUnassignedDecision.getTargetNode().getId(), allocateUnassignedDecision.getAllocationId(), shard.primary() ? ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE : allocation.clusterInfo().getShardSize(shard, ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE), allocation.changes());
} else {
unassignedIterator.removeAndIgnore(allocateUnassignedDecision.getAllocationStatus(), allocation.changes());
}
}
}
use of org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision in project crate by crate.
the class BalancedShardsAllocator method decideShardAllocation.
@Override
public ShardAllocationDecision decideShardAllocation(final ShardRouting shard, final RoutingAllocation allocation) {
Balancer balancer = new Balancer(LOGGER, allocation, weightFunction, threshold);
AllocateUnassignedDecision allocateUnassignedDecision = AllocateUnassignedDecision.NOT_TAKEN;
MoveDecision moveDecision = MoveDecision.NOT_TAKEN;
if (shard.unassigned()) {
allocateUnassignedDecision = balancer.decideAllocateUnassigned(shard, Set.of());
} else {
moveDecision = balancer.decideMove(shard);
if (moveDecision.isDecisionTaken() && moveDecision.canRemain()) {
MoveDecision rebalanceDecision = balancer.decideRebalance(shard);
moveDecision = rebalanceDecision.withRemainDecision(moveDecision.getCanRemainDecision());
}
}
return new ShardAllocationDecision(allocateUnassignedDecision, moveDecision);
}
use of org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision in project crate by crate.
the class BaseGatewayShardAllocator method allocateUnassigned.
/**
* Allocate unassigned shards to nodes (if any) where valid copies of the shard already exist.
* It is up to the individual implementations of {@link #makeAllocationDecision(ShardRouting, RoutingAllocation, Logger)}
* to make decisions on assigning shards to nodes.
*
* @param allocation the allocation state container object
*/
public void allocateUnassigned(RoutingAllocation allocation) {
final RoutingNodes routingNodes = allocation.routingNodes();
final RoutingNodes.UnassignedShards.UnassignedIterator unassignedIterator = routingNodes.unassigned().iterator();
while (unassignedIterator.hasNext()) {
final ShardRouting shard = unassignedIterator.next();
final AllocateUnassignedDecision allocateUnassignedDecision = makeAllocationDecision(shard, allocation, logger);
if (allocateUnassignedDecision.isDecisionTaken() == false) {
// no decision was taken by this allocator
continue;
}
if (allocateUnassignedDecision.getAllocationDecision() == AllocationDecision.YES) {
unassignedIterator.initialize(allocateUnassignedDecision.getTargetNode().getId(), allocateUnassignedDecision.getAllocationId(), shard.primary() ? ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE : allocation.clusterInfo().getShardSize(shard, ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE), allocation.changes());
} else {
unassignedIterator.removeAndIgnore(allocateUnassignedDecision.getAllocationStatus(), allocation.changes());
}
}
}
use of org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision in project elasticsearch by elastic.
the class BalancedShardsAllocator method decideShardAllocation.
@Override
public ShardAllocationDecision decideShardAllocation(final ShardRouting shard, final RoutingAllocation allocation) {
Balancer balancer = new Balancer(logger, allocation, weightFunction, threshold);
AllocateUnassignedDecision allocateUnassignedDecision = AllocateUnassignedDecision.NOT_TAKEN;
MoveDecision moveDecision = MoveDecision.NOT_TAKEN;
if (shard.unassigned()) {
allocateUnassignedDecision = balancer.decideAllocateUnassigned(shard, Sets.newHashSet());
} else {
moveDecision = balancer.decideMove(shard);
if (moveDecision.isDecisionTaken() && moveDecision.canRemain()) {
MoveDecision rebalanceDecision = balancer.decideRebalance(shard);
moveDecision = rebalanceDecision.withRemainDecision(moveDecision.getCanRemainDecision());
}
}
return new ShardAllocationDecision(allocateUnassignedDecision, moveDecision);
}
Aggregations