Search in sources :

Example 6 with RoutingTable

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

the class AllocationService method adaptAutoExpandReplicas.

/**
 * Checks if there are replicas with the auto-expand feature that need to be adapted.
 * Returns an updated cluster state if changes were necessary, or the identical cluster if no changes were required.
 */
public ClusterState adaptAutoExpandReplicas(ClusterState clusterState) {
    RoutingAllocation allocation = new RoutingAllocation(allocationDeciders, clusterState.getRoutingNodes(), clusterState, clusterInfoService.getClusterInfo(), snapshotsInfoService.snapshotShardSizes(), currentNanoTime());
    final Map<Integer, List<String>> autoExpandReplicaChanges = AutoExpandReplicas.getAutoExpandReplicaChanges(clusterState.metadata(), allocation);
    if (autoExpandReplicaChanges.isEmpty()) {
        return clusterState;
    } else {
        final RoutingTable.Builder routingTableBuilder = RoutingTable.builder(clusterState.routingTable());
        final Metadata.Builder metadataBuilder = Metadata.builder(clusterState.metadata());
        for (Map.Entry<Integer, List<String>> entry : autoExpandReplicaChanges.entrySet()) {
            final int numberOfReplicas = entry.getKey();
            final String[] indices = entry.getValue().toArray(new String[entry.getValue().size()]);
            // we do *not* update the in sync allocation ids as they will be removed upon the first index
            // operation which make these copies stale
            routingTableBuilder.updateNumberOfReplicas(numberOfReplicas, indices);
            metadataBuilder.updateNumberOfReplicas(numberOfReplicas, indices);
            // update settings version for each index
            for (final String index : indices) {
                final IndexMetadata indexMetadata = metadataBuilder.get(index);
                final IndexMetadata.Builder indexMetadataBuilder = new IndexMetadata.Builder(indexMetadata).settingsVersion(1 + indexMetadata.getSettingsVersion());
                metadataBuilder.put(indexMetadataBuilder);
            }
            logger.info("updating number_of_replicas to [{}] for indices {}", numberOfReplicas, indices);
        }
        final ClusterState fixedState = ClusterState.builder(clusterState).routingTable(routingTableBuilder.build()).metadata(metadataBuilder).build();
        assert AutoExpandReplicas.getAutoExpandReplicaChanges(fixedState.metadata(), allocation).isEmpty();
        return fixedState;
    }
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap) Map(java.util.Map)

Example 7 with RoutingTable

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

the class MetadataCreateIndexService method clusterStateCreateIndex.

/**
 * Creates the index into the cluster state applying the provided blocks. The final cluster state will contain an updated routing
 * table based on the live nodes.
 */
static ClusterState clusterStateCreateIndex(ClusterState currentState, Set<ClusterBlock> clusterBlocks, IndexMetadata indexMetadata, BiFunction<ClusterState, String, ClusterState> rerouteRoutingTable, BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer) {
    Metadata.Builder builder = Metadata.builder(currentState.metadata()).put(indexMetadata, false);
    if (metadataTransformer != null) {
        metadataTransformer.accept(builder, indexMetadata);
    }
    Metadata newMetadata = builder.build();
    String indexName = indexMetadata.getIndex().getName();
    ClusterBlocks.Builder blocks = createClusterBlocksBuilder(currentState, indexName, clusterBlocks);
    blocks.updateBlocks(indexMetadata);
    ClusterState updatedState = ClusterState.builder(currentState).blocks(blocks).metadata(newMetadata).build();
    RoutingTable.Builder routingTableBuilder = RoutingTable.builder(updatedState.routingTable()).addAsNew(updatedState.metadata().index(indexName));
    updatedState = ClusterState.builder(updatedState).routingTable(routingTableBuilder.build()).build();
    return rerouteRoutingTable.apply(updatedState, "index [" + indexName + "] created");
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks)

Example 8 with RoutingTable

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

the class MetadataIndexStateService method closeRoutingTable.

/**
 * Step 3 - Move index states from OPEN to CLOSE in cluster state for indices that are ready for closing.
 */
static Tuple<ClusterState, Collection<IndexResult>> closeRoutingTable(final ClusterState currentState, final Map<Index, ClusterBlock> blockedIndices, final Map<Index, IndexResult> verifyResult) {
    // Remove the index routing table of closed indices if the cluster is in a mixed version
    // that does not support the replication of closed indices
    final boolean removeRoutingTable = currentState.nodes().getMinNodeVersion().before(LegacyESVersion.V_7_2_0);
    final Metadata.Builder metadata = Metadata.builder(currentState.metadata());
    final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
    final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
    final Set<String> closedIndices = new HashSet<>();
    Map<Index, IndexResult> closingResults = new HashMap<>(verifyResult);
    for (Map.Entry<Index, IndexResult> result : verifyResult.entrySet()) {
        final Index index = result.getKey();
        final boolean acknowledged = result.getValue().hasFailures() == false;
        try {
            if (acknowledged == false) {
                logger.debug("verification of shards before closing {} failed [{}]", index, result);
                continue;
            }
            final IndexMetadata indexMetadata = metadata.getSafe(index);
            if (indexMetadata.getState() == IndexMetadata.State.CLOSE) {
                logger.debug("verification of shards before closing {} succeeded but index is already closed", index);
                assert currentState.blocks().hasIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
                continue;
            }
            final ClusterBlock closingBlock = blockedIndices.get(index);
            assert closingBlock != null;
            if (currentState.blocks().hasIndexBlock(index.getName(), closingBlock) == false) {
                // we should report error in this case as the index can be left as open.
                closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but block has been removed in the meantime")));
                logger.debug("verification of shards before closing {} succeeded but block has been removed in the meantime", index);
                continue;
            }
            // Check if index closing conflicts with any running restores
            Set<Index> restoringIndices = RestoreService.restoringIndices(currentState, singleton(index));
            if (restoringIndices.isEmpty() == false) {
                closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but index is being restored in the meantime")));
                logger.debug("verification of shards before closing {} succeeded but index is being restored in the meantime", index);
                continue;
            }
            // Check if index closing conflicts with any running snapshots
            Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, singleton(index));
            if (snapshottingIndices.isEmpty() == false) {
                closingResults.put(result.getKey(), new IndexResult(result.getKey(), new IllegalStateException("verification of shards before closing " + index + " succeeded but index is being snapshot in the meantime")));
                logger.debug("verification of shards before closing {} succeeded but index is being snapshot in the meantime", index);
                continue;
            }
            blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID);
            blocks.addIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
            final IndexMetadata.Builder updatedMetadata = IndexMetadata.builder(indexMetadata).state(IndexMetadata.State.CLOSE);
            if (removeRoutingTable) {
                metadata.put(updatedMetadata);
                routingTable.remove(index.getName());
            } else {
                metadata.put(updatedMetadata.settingsVersion(indexMetadata.getSettingsVersion() + 1).settings(Settings.builder().put(indexMetadata.getSettings()).put(VERIFIED_BEFORE_CLOSE_SETTING.getKey(), true)));
                routingTable.addAsFromOpenToClose(metadata.getSafe(index));
            }
            logger.debug("closing index {} succeeded", index);
            closedIndices.add(index.getName());
        } catch (final IndexNotFoundException e) {
            logger.debug("index {} has been deleted since it was blocked before closing, ignoring", index);
        }
    }
    logger.info("completed closing of indices {}", closedIndices);
    return Tuple.tuple(ClusterState.builder(currentState).blocks(blocks).metadata(metadata).routingTable(routingTable.build()).build(), closingResults.values());
}
Also used : ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) HashMap(java.util.HashMap) Index(org.opensearch.index.Index) ClusterBlock(org.opensearch.cluster.block.ClusterBlock) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) IndexResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.IndexResult) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) Map(java.util.Map) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) Collections.unmodifiableMap(java.util.Collections.unmodifiableMap) HashSet(java.util.HashSet)

Example 9 with RoutingTable

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

the class MetadataIndexStateService method finalizeBlock.

/**
 * Finalizes the addition of blocks by turning the temporary UUID-based blocks into full blocks.
 * @param currentState the cluster state to update
 * @param blockedIndices the indices and their temporary UUID-based blocks to convert
 * @param verifyResult the index-level results for adding the block
 * @param block the full block to convert to
 * @return the updated cluster state, as well as the (failed and successful) index-level results for adding the block
 */
static Tuple<ClusterState, Collection<AddBlockResult>> finalizeBlock(final ClusterState currentState, final Map<Index, ClusterBlock> blockedIndices, final Map<Index, AddBlockResult> verifyResult, final APIBlock block) {
    final Metadata.Builder metadata = Metadata.builder(currentState.metadata());
    final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
    final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
    final Set<String> effectivelyBlockedIndices = new HashSet<>();
    Map<Index, AddBlockResult> blockingResults = new HashMap<>(verifyResult);
    for (Map.Entry<Index, AddBlockResult> result : verifyResult.entrySet()) {
        final Index index = result.getKey();
        final boolean acknowledged = result.getValue().hasFailures() == false;
        try {
            if (acknowledged == false) {
                logger.debug("verification of shards before blocking {} failed [{}]", index, result);
                continue;
            }
            final IndexMetadata indexMetadata = metadata.getSafe(index);
            final ClusterBlock tempBlock = blockedIndices.get(index);
            assert tempBlock != null;
            assert tempBlock.uuid() != null;
            final ClusterBlock currentBlock = currentState.blocks().getIndexBlockWithId(index.getName(), tempBlock.id());
            if (currentBlock != null && currentBlock.equals(block.block)) {
                logger.debug("verification of shards for {} succeeded, but block finalization already occurred" + " (possibly for another block) [{}]", index, result);
                continue;
            }
            if (currentBlock == null || currentBlock.equals(tempBlock) == false) {
                // we should report error in this case as the index can be left as open.
                blockingResults.put(result.getKey(), new AddBlockResult(result.getKey(), new IllegalStateException("verification of shards before blocking " + index + " succeeded but block has been removed in the meantime")));
                logger.debug("verification of shards before blocking {} succeeded but block has been removed in the meantime", index);
                continue;
            }
            assert currentBlock != null && currentBlock.equals(tempBlock) && currentBlock.id() == block.block.id();
            blocks.removeIndexBlockWithId(index.getName(), tempBlock.id());
            blocks.addIndexBlock(index.getName(), block.block);
            logger.debug("add block {} to index {} succeeded", block.block, index);
            effectivelyBlockedIndices.add(index.getName());
        } catch (final IndexNotFoundException e) {
            logger.debug("index {} has been deleted since blocking it started, ignoring", index);
        }
    }
    logger.info("completed adding block {} to indices {}", block.name, effectivelyBlockedIndices);
    return Tuple.tuple(ClusterState.builder(currentState).blocks(blocks).metadata(metadata).routingTable(routingTable.build()).build(), blockingResults.values());
}
Also used : ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) HashMap(java.util.HashMap) Index(org.opensearch.index.Index) AddBlockResult(org.opensearch.action.admin.indices.readonly.AddIndexBlockResponse.AddBlockResult) ClusterBlock(org.opensearch.cluster.block.ClusterBlock) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) IndexRoutingTable(org.opensearch.cluster.routing.IndexRoutingTable) RoutingTable(org.opensearch.cluster.routing.RoutingTable) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) Map(java.util.Map) ImmutableOpenIntMap(org.opensearch.common.collect.ImmutableOpenIntMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) Collections.unmodifiableMap(java.util.Collections.unmodifiableMap) HashSet(java.util.HashSet)

Example 10 with RoutingTable

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

the class PersistentTasksClusterServiceTests method significantChange.

private ClusterState significantChange(ClusterState clusterState) {
    ClusterState.Builder builder = ClusterState.builder(clusterState);
    PersistentTasksCustomMetadata tasks = clusterState.getMetadata().custom(PersistentTasksCustomMetadata.TYPE);
    if (tasks != null) {
        if (randomBoolean()) {
            for (PersistentTask<?> task : tasks.tasks()) {
                if (task.isAssigned() && clusterState.nodes().nodeExists(task.getExecutorNode())) {
                    logger.info("removed node {}", task.getExecutorNode());
                    builder.nodes(DiscoveryNodes.builder(clusterState.nodes()).remove(task.getExecutorNode()));
                    return builder.build();
                }
            }
        }
    }
    boolean tasksOrNodesChanged = false;
    // add a new unassigned task
    if (hasAssignableTasks(tasks, clusterState.nodes()) == false) {
        // we don't have any unassigned tasks - add some
        if (randomBoolean()) {
            logger.info("added random task");
            addRandomTask(builder, Metadata.builder(clusterState.metadata()), PersistentTasksCustomMetadata.builder(tasks), null);
            tasksOrNodesChanged = true;
        } else {
            logger.info("added unassignable task with custom assignment message");
            addRandomTask(builder, Metadata.builder(clusterState.metadata()), PersistentTasksCustomMetadata.builder(tasks), new Assignment(null, "change me"), "never_assign");
            tasksOrNodesChanged = true;
        }
    }
    // add a node if there are unassigned tasks
    if (clusterState.nodes().getNodes().isEmpty()) {
        logger.info("added random node");
        builder.nodes(DiscoveryNodes.builder(clusterState.nodes()).add(newNode(randomAlphaOfLength(10))));
        tasksOrNodesChanged = true;
    }
    if (tasksOrNodesChanged == false) {
        // change routing table to simulate a change
        logger.info("changed routing table");
        Metadata.Builder metadata = Metadata.builder(clusterState.metadata());
        RoutingTable.Builder routingTable = RoutingTable.builder(clusterState.routingTable());
        changeRoutingTable(metadata, routingTable);
        builder.metadata(metadata).routingTable(routingTable.build());
    }
    return builder.build();
}
Also used : Assignment(org.opensearch.persistent.PersistentTasksCustomMetadata.Assignment) ClusterState(org.opensearch.cluster.ClusterState) RoutingTable(org.opensearch.cluster.routing.RoutingTable) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata)

Aggregations

RoutingTable (org.opensearch.cluster.routing.RoutingTable)227 ClusterState (org.opensearch.cluster.ClusterState)193 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)190 Metadata (org.opensearch.cluster.metadata.Metadata)187 ShardRouting (org.opensearch.cluster.routing.ShardRouting)81 IndexShardRoutingTable (org.opensearch.cluster.routing.IndexShardRoutingTable)58 IndexRoutingTable (org.opensearch.cluster.routing.IndexRoutingTable)55 RoutingNodes (org.opensearch.cluster.routing.RoutingNodes)42 AllocationService (org.opensearch.cluster.routing.allocation.AllocationService)42 ShardId (org.opensearch.index.shard.ShardId)35 DiscoveryNodes (org.opensearch.cluster.node.DiscoveryNodes)34 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)33 Settings (org.opensearch.common.settings.Settings)33 Index (org.opensearch.index.Index)30 HashSet (java.util.HashSet)29 TestGatewayAllocator (org.opensearch.test.gateway.TestGatewayAllocator)29 ImmutableOpenMap (org.opensearch.common.collect.ImmutableOpenMap)28 ClusterSettings (org.opensearch.common.settings.ClusterSettings)28 RoutingNode (org.opensearch.cluster.routing.RoutingNode)24 BalancedShardsAllocator (org.opensearch.cluster.routing.allocation.allocator.BalancedShardsAllocator)23