use of org.elasticsearch.cluster.routing.RoutingNode in project elasticsearch by elastic.
the class IndicesStore method clusterChanged.
@Override
public void clusterChanged(ClusterChangedEvent event) {
if (!event.routingTableChanged()) {
return;
}
if (event.state().blocks().disableStatePersistence()) {
return;
}
RoutingTable routingTable = event.state().routingTable();
// - closed indices don't need to be removed from the cache but we do it anyway for code simplicity
for (Iterator<ShardId> it = folderNotFoundCache.iterator(); it.hasNext(); ) {
ShardId shardId = it.next();
if (routingTable.hasIndex(shardId.getIndex()) == false) {
it.remove();
}
}
// remove entries from cache which are allocated to this node
final String localNodeId = event.state().nodes().getLocalNodeId();
RoutingNode localRoutingNode = event.state().getRoutingNodes().node(localNodeId);
if (localRoutingNode != null) {
for (ShardRouting routing : localRoutingNode) {
folderNotFoundCache.remove(routing.shardId());
}
}
for (IndexRoutingTable indexRoutingTable : routingTable) {
// Note, closed indices will not have any routing information, so won't be deleted
for (IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) {
ShardId shardId = indexShardRoutingTable.shardId();
if (folderNotFoundCache.contains(shardId) == false && shardCanBeDeleted(localNodeId, indexShardRoutingTable)) {
IndexService indexService = indicesService.indexService(indexRoutingTable.getIndex());
final IndexSettings indexSettings;
if (indexService == null) {
IndexMetaData indexMetaData = event.state().getMetaData().getIndexSafe(indexRoutingTable.getIndex());
indexSettings = new IndexSettings(indexMetaData, settings);
} else {
indexSettings = indexService.getIndexSettings();
}
IndicesService.ShardDeletionCheckResult shardDeletionCheckResult = indicesService.canDeleteShardContent(shardId, indexSettings);
switch(shardDeletionCheckResult) {
case FOLDER_FOUND_CAN_DELETE:
deleteShardIfExistElseWhere(event.state(), indexShardRoutingTable);
break;
case NO_FOLDER_FOUND:
folderNotFoundCache.add(shardId);
break;
case NO_LOCAL_STORAGE:
assert false : "shard deletion only runs on data nodes which always have local storage";
// nothing to do
break;
case STILL_ALLOCATED:
// nothing to do
break;
case SHARED_FILE_SYSTEM:
// nothing to do
break;
default:
assert false : "unknown shard deletion check result: " + shardDeletionCheckResult;
}
}
}
}
}
use of org.elasticsearch.cluster.routing.RoutingNode in project elasticsearch by elastic.
the class BalancedSingleShardTests method testDontBalanceShardWhenThresholdNotMet.
public void testDontBalanceShardWhenThresholdNotMet() {
AllocationDecider canAllocateDecider = new AllocationDecider(Settings.EMPTY) {
@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
return Decision.YES;
}
};
// ridiculously high threshold setting so we won't rebalance
Settings balancerSettings = Settings.builder().put(BalancedShardsAllocator.THRESHOLD_SETTING.getKey(), 1000f).build();
Tuple<ClusterState, MoveDecision> rebalance = setupStateAndRebalance(canAllocateDecider, balancerSettings, false);
ClusterState clusterState = rebalance.v1();
MoveDecision rebalanceDecision = rebalance.v2();
assertEquals(Type.YES, rebalanceDecision.getClusterRebalanceDecision().type());
assertEquals(AllocationDecision.NO, rebalanceDecision.getAllocationDecision());
assertNotNull(rebalanceDecision.getExplanation());
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.RoutingNode in project elasticsearch by elastic.
the class BalanceConfigurationTests method assertIndexBalance.
private void assertIndexBalance(RoutingTable routingTable, RoutingNodes nodes, int numberOfNodes, int numberOfIndices, int numberOfReplicas, int numberOfShards, float treshold) {
final int numShards = numberOfShards * (numberOfReplicas + 1);
final float avgNumShards = (float) (numShards) / (float) (numberOfNodes);
final int minAvgNumberOfShards = Math.round(Math.round(Math.floor(avgNumShards - treshold)));
final int maxAvgNumberOfShards = Math.round(Math.round(Math.ceil(avgNumShards + treshold)));
for (ObjectCursor<String> index : routingTable.indicesRouting().keys()) {
for (RoutingNode node : nodes) {
// logger.info(node.nodeId() +":"+index+ ": " + node.shardsWithState(index, INITIALIZING, STARTED).size() + " shards ("+minAvgNumberOfShards+" to "+maxAvgNumberOfShards+")");
assertThat(node.shardsWithState(index.value, STARTED).size(), Matchers.greaterThanOrEqualTo(minAvgNumberOfShards));
assertThat(node.shardsWithState(index.value, STARTED).size(), Matchers.lessThanOrEqualTo(maxAvgNumberOfShards));
}
}
}
use of org.elasticsearch.cluster.routing.RoutingNode 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.RoutingNode 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());
}
}
}
Aggregations