Search in sources :

Example 1 with RoutingAllocation

use of org.opensearch.cluster.routing.allocation.RoutingAllocation in project OpenSearch by opensearch-project.

the class TransportClusterAllocationExplainAction method masterOperation.

@Override
protected void masterOperation(final ClusterAllocationExplainRequest request, final ClusterState state, final ActionListener<ClusterAllocationExplainResponse> listener) {
    final RoutingNodes routingNodes = state.getRoutingNodes();
    final ClusterInfo clusterInfo = clusterInfoService.getClusterInfo();
    final RoutingAllocation allocation = new RoutingAllocation(allocationDeciders, routingNodes, state, clusterInfo, snapshotsInfoService.snapshotShardSizes(), System.nanoTime());
    ShardRouting shardRouting = findShardToExplain(request, allocation);
    logger.debug("explaining the allocation for [{}], found shard [{}]", request, shardRouting);
    ClusterAllocationExplanation cae = explainShard(shardRouting, allocation, request.includeDiskInfo() ? clusterInfo : null, request.includeYesDecisions(), allocationService);
    listener.onResponse(new ClusterAllocationExplainResponse(cae));
}
Also used : ClusterInfo(org.opensearch.cluster.ClusterInfo) RoutingNodes(org.opensearch.cluster.routing.RoutingNodes) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation) ShardRouting(org.opensearch.cluster.routing.ShardRouting)

Example 2 with RoutingAllocation

use of org.opensearch.cluster.routing.allocation.RoutingAllocation in project OpenSearch by opensearch-project.

the class GatewayAllocator method ensureAsyncFetchStorePrimaryRecency.

/**
 * Clear the fetched data for the primary to ensure we do not cancel recoveries based on excessively stale data.
 */
private void ensureAsyncFetchStorePrimaryRecency(RoutingAllocation allocation) {
    DiscoveryNodes nodes = allocation.nodes();
    if (hasNewNodes(nodes)) {
        final Set<String> newEphemeralIds = StreamSupport.stream(nodes.getDataNodes().spliterator(), false).map(node -> node.value.getEphemeralId()).collect(Collectors.toSet());
        // Invalidate the cache if a data node has been added to the cluster. This ensures that we do not cancel a recovery if a node
        // drops out, we fetch the shard data, then some indexing happens and then the node rejoins the cluster again. There are other
        // ways we could decide to cancel a recovery based on stale data (e.g. changing allocation filters or a primary failure) but
        // making the wrong decision here is not catastrophic so we only need to cover the common case.
        logger.trace(() -> new ParameterizedMessage("new nodes {} found, clearing primary async-fetch-store cache", Sets.difference(newEphemeralIds, lastSeenEphemeralIds)));
        asyncFetchStore.values().forEach(fetch -> clearCacheForPrimary(fetch, allocation));
        // recalc to also (lazily) clear out old nodes.
        this.lastSeenEphemeralIds = newEphemeralIds;
    }
}
Also used : DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation) Priority(org.opensearch.common.Priority) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Releasables(org.opensearch.common.lease.Releasables) ConcurrentMap(java.util.concurrent.ConcurrentMap) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) ObjectObjectCursor(com.carrotsearch.hppc.cursors.ObjectObjectCursor) BaseNodeResponse(org.opensearch.action.support.nodes.BaseNodeResponse) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) RerouteService(org.opensearch.cluster.routing.RerouteService) Inject(org.opensearch.common.inject.Inject) StreamSupport(java.util.stream.StreamSupport) ActionListener(org.opensearch.action.ActionListener) BaseNodesResponse(org.opensearch.action.support.nodes.BaseNodesResponse) Set(java.util.Set) Collectors(java.util.stream.Collectors) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ShardId(org.opensearch.index.shard.ShardId) TransportNodesListShardStoreMetadata(org.opensearch.indices.store.TransportNodesListShardStoreMetadata) Sets(org.opensearch.common.util.set.Sets) List(java.util.List) Logger(org.apache.logging.log4j.Logger) FailedShard(org.opensearch.cluster.routing.allocation.FailedShard) ExistingShardsAllocator(org.opensearch.cluster.routing.allocation.ExistingShardsAllocator) AllocateUnassignedDecision(org.opensearch.cluster.routing.allocation.AllocateUnassignedDecision) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes)

Example 3 with RoutingAllocation

use of org.opensearch.cluster.routing.allocation.RoutingAllocation in project OpenSearch by opensearch-project.

the class EnableAllocationDecider method canAllocate.

@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingAllocation allocation) {
    if (allocation.ignoreDisable()) {
        return allocation.decision(Decision.YES, NAME, "explicitly ignoring any disabling of allocation due to manual allocation commands via the reroute API");
    }
    final IndexMetadata indexMetadata = allocation.metadata().getIndexSafe(shardRouting.index());
    final Allocation enable;
    final boolean usedIndexSetting;
    if (INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.exists(indexMetadata.getSettings())) {
        enable = INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.get(indexMetadata.getSettings());
        usedIndexSetting = true;
    } else {
        enable = this.enableAllocation;
        usedIndexSetting = false;
    }
    switch(enable) {
        case ALL:
            return allocation.decision(Decision.YES, NAME, "all allocations are allowed");
        case NONE:
            return allocation.decision(Decision.NO, NAME, "no allocations are allowed due to %s", setting(enable, usedIndexSetting));
        case NEW_PRIMARIES:
            if (shardRouting.primary() && shardRouting.active() == false && shardRouting.recoverySource().getType() != RecoverySource.Type.EXISTING_STORE) {
                return allocation.decision(Decision.YES, NAME, "new primary allocations are allowed");
            } else {
                return allocation.decision(Decision.NO, NAME, "non-new primary allocations are forbidden due to %s", setting(enable, usedIndexSetting));
            }
        case PRIMARIES:
            if (shardRouting.primary()) {
                return allocation.decision(Decision.YES, NAME, "primary allocations are allowed");
            } else {
                return allocation.decision(Decision.NO, NAME, "replica allocations are forbidden due to %s", setting(enable, usedIndexSetting));
            }
        default:
            throw new IllegalStateException("Unknown allocation option");
    }
}
Also used : RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata)

Example 4 with RoutingAllocation

use of org.opensearch.cluster.routing.allocation.RoutingAllocation in project OpenSearch by opensearch-project.

the class ClusterAllocationExplainActionTests method testFindShardAssignedToNode.

public void testFindShardAssignedToNode() {
    // find shard with given node
    final boolean primary = randomBoolean();
    ShardRoutingState[] replicaStates = new ShardRoutingState[0];
    if (primary == false) {
        replicaStates = new ShardRoutingState[] { ShardRoutingState.STARTED };
    }
    ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), ShardRoutingState.STARTED, replicaStates);
    ShardRouting shardToExplain = primary ? clusterState.getRoutingTable().index("idx").shard(0).primaryShard() : clusterState.getRoutingTable().index("idx").shard(0).replicaShards().get(0);
    ClusterAllocationExplainRequest request = new ClusterAllocationExplainRequest("idx", 0, primary, shardToExplain.currentNodeId());
    RoutingAllocation allocation = routingAllocation(clusterState);
    ShardRouting foundShard = findShardToExplain(request, allocation);
    assertEquals(shardToExplain, foundShard);
    // shard is not assigned to given node
    String explainNode = null;
    for (RoutingNode routingNode : clusterState.getRoutingNodes()) {
        if (routingNode.nodeId().equals(shardToExplain.currentNodeId()) == false) {
            explainNode = routingNode.nodeId();
            break;
        }
    }
    final ClusterAllocationExplainRequest failingRequest = new ClusterAllocationExplainRequest("idx", 0, primary, explainNode);
    expectThrows(IllegalArgumentException.class, () -> findShardToExplain(failingRequest, allocation));
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) RoutingNode(org.opensearch.cluster.routing.RoutingNode) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) ShardRouting(org.opensearch.cluster.routing.ShardRouting) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation)

Example 5 with RoutingAllocation

use of org.opensearch.cluster.routing.allocation.RoutingAllocation in project OpenSearch by opensearch-project.

the class ClusterAllocationExplainActionTests method testInitializingOrRelocatingShardExplanation.

public void testInitializingOrRelocatingShardExplanation() throws Exception {
    ShardRoutingState shardRoutingState = randomFrom(ShardRoutingState.INITIALIZING, ShardRoutingState.RELOCATING);
    ClusterState clusterState = ClusterStateCreationUtils.state("idx", randomBoolean(), shardRoutingState);
    ShardRouting shard = clusterState.getRoutingTable().index("idx").shard(0).primaryShard();
    RoutingAllocation allocation = new RoutingAllocation(new AllocationDeciders(Collections.emptyList()), clusterState.getRoutingNodes(), clusterState, null, null, System.nanoTime());
    ClusterAllocationExplanation cae = TransportClusterAllocationExplainAction.explainShard(shard, allocation, null, randomBoolean(), new AllocationService(null, new TestGatewayAllocator(), new ShardsAllocator() {

        @Override
        public void allocate(RoutingAllocation allocation) {
        // no-op
        }

        @Override
        public ShardAllocationDecision decideShardAllocation(ShardRouting shard, RoutingAllocation allocation) {
            if (shard.initializing() || shard.relocating()) {
                return ShardAllocationDecision.NOT_TAKEN;
            } else {
                throw new UnsupportedOperationException("cannot explain");
            }
        }
    }, null, null));
    assertEquals(shard.currentNodeId(), cae.getCurrentNode().getId());
    assertFalse(cae.getShardAllocationDecision().isDecisionTaken());
    assertFalse(cae.getShardAllocationDecision().getAllocateDecision().isDecisionTaken());
    assertFalse(cae.getShardAllocationDecision().getMoveDecision().isDecisionTaken());
    XContentBuilder builder = XContentFactory.jsonBuilder();
    cae.toXContent(builder, ToXContent.EMPTY_PARAMS);
    String explanation;
    if (shardRoutingState == ShardRoutingState.RELOCATING) {
        explanation = "the shard is in the process of relocating from node [] to node [], wait until " + "relocation has completed";
    } else {
        explanation = "the shard is in the process of initializing on node [], " + "wait until initialization has completed";
    }
    assertEquals("{\"index\":\"idx\",\"shard\":0,\"primary\":true,\"current_state\":\"" + shardRoutingState.toString().toLowerCase(Locale.ROOT) + "\"" + (shard.unassignedInfo() != null ? ",\"unassigned_info\":{" + "\"reason\":\"" + shard.unassignedInfo().getReason() + "\"," + "\"at\":\"" + UnassignedInfo.DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(shard.unassignedInfo().getUnassignedTimeInMillis())) + "\"," + "\"last_allocation_status\":\"" + AllocationDecision.fromAllocationStatus(shard.unassignedInfo().getLastAllocationStatus()) + "\"}" : "") + ",\"current_node\":" + "{\"id\":\"" + cae.getCurrentNode().getId() + "\",\"name\":\"" + cae.getCurrentNode().getName() + "\",\"transport_address\":\"" + cae.getCurrentNode().getAddress() + "\"},\"explanation\":\"" + explanation + "\"}", Strings.toString(builder));
}
Also used : TestGatewayAllocator(org.opensearch.test.gateway.TestGatewayAllocator) ClusterState(org.opensearch.cluster.ClusterState) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) AllocationDeciders(org.opensearch.cluster.routing.allocation.decider.AllocationDeciders) ShardsAllocator(org.opensearch.cluster.routing.allocation.allocator.ShardsAllocator) ShardRouting(org.opensearch.cluster.routing.ShardRouting) RoutingAllocation(org.opensearch.cluster.routing.allocation.RoutingAllocation) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder)

Aggregations

RoutingAllocation (org.opensearch.cluster.routing.allocation.RoutingAllocation)62 ShardRouting (org.opensearch.cluster.routing.ShardRouting)23 StoreFileMetadata (org.opensearch.index.store.StoreFileMetadata)20 ClusterState (org.opensearch.cluster.ClusterState)18 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)15 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)15 RoutingTable (org.opensearch.cluster.routing.RoutingTable)15 Metadata (org.opensearch.cluster.metadata.Metadata)12 UnassignedInfo (org.opensearch.cluster.routing.UnassignedInfo)11 RoutingNode (org.opensearch.cluster.routing.RoutingNode)10 ClusterSettings (org.opensearch.common.settings.ClusterSettings)10 ClusterInfo (org.opensearch.cluster.ClusterInfo)9 Matchers.containsString (org.hamcrest.Matchers.containsString)8 RoutingNodes (org.opensearch.cluster.routing.RoutingNodes)8 AllocationService (org.opensearch.cluster.routing.allocation.AllocationService)8 TestShardRouting (org.opensearch.cluster.routing.TestShardRouting)7 ImmutableOpenMap (org.opensearch.common.collect.ImmutableOpenMap)7 ShardId (org.opensearch.index.shard.ShardId)7 TestGatewayAllocator (org.opensearch.test.gateway.TestGatewayAllocator)7 DiskUsage (org.opensearch.cluster.DiskUsage)6