Search in sources :

Example 16 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class InternalClusterInfoService method clusterChanged.

@Override
public void clusterChanged(ClusterChangedEvent event) {
    if (event.localNodeMaster() && refreshAndRescheduleRunnable.get() == null) {
        logger.trace("elected as master, scheduling cluster info update tasks");
        executeRefresh(event.state(), "became master");
        final RefreshAndRescheduleRunnable newRunnable = new RefreshAndRescheduleRunnable();
        refreshAndRescheduleRunnable.set(newRunnable);
        threadPool.scheduleUnlessShuttingDown(updateFrequency, REFRESH_EXECUTOR, newRunnable);
    } else if (event.localNodeMaster() == false) {
        refreshAndRescheduleRunnable.set(null);
        return;
    }
    if (enabled == false) {
        return;
    }
    // Refresh if a data node was added
    for (DiscoveryNode addedNode : event.nodesDelta().addedNodes()) {
        if (addedNode.isDataNode()) {
            executeRefresh(event.state(), "data node added");
            break;
        }
    }
    // Clean up info for any removed nodes
    for (DiscoveryNode removedNode : event.nodesDelta().removedNodes()) {
        if (removedNode.isDataNode()) {
            logger.trace("Removing node from cluster info: {}", removedNode.getId());
            if (leastAvailableSpaceUsages.containsKey(removedNode.getId())) {
                ImmutableOpenMap.Builder<String, DiskUsage> newMaxUsages = ImmutableOpenMap.builder(leastAvailableSpaceUsages);
                newMaxUsages.remove(removedNode.getId());
                leastAvailableSpaceUsages = newMaxUsages.build();
            }
            if (mostAvailableSpaceUsages.containsKey(removedNode.getId())) {
                ImmutableOpenMap.Builder<String, DiskUsage> newMinUsages = ImmutableOpenMap.builder(mostAvailableSpaceUsages);
                newMinUsages.remove(removedNode.getId());
                mostAvailableSpaceUsages = newMinUsages.build();
            }
        }
    }
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) ImmutableOpenMap(org.opensearch.common.collect.ImmutableOpenMap)

Example 17 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class NodeConnectionsService method disconnectFromNodesExcept.

/**
 * Disconnect from any nodes to which we are currently connected which do not appear in the given nodes. Does not wait for the
 * disconnections to complete, because they might have to wait for ongoing connection attempts first.
 */
public void disconnectFromNodesExcept(DiscoveryNodes discoveryNodes) {
    final List<Runnable> runnables = new ArrayList<>();
    synchronized (mutex) {
        final Set<DiscoveryNode> nodesToDisconnect = new HashSet<>(targetsByNode.keySet());
        for (final DiscoveryNode discoveryNode : discoveryNodes) {
            nodesToDisconnect.remove(discoveryNode);
        }
        for (final DiscoveryNode discoveryNode : nodesToDisconnect) {
            runnables.add(targetsByNode.get(discoveryNode).disconnect());
        }
    }
    runnables.forEach(Runnable::run);
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 18 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class JoinTaskExecutor method becomeMasterAndTrimConflictingNodes.

protected ClusterState.Builder becomeMasterAndTrimConflictingNodes(ClusterState currentState, List<Task> joiningNodes) {
    assert currentState.nodes().getMasterNodeId() == null : currentState;
    DiscoveryNodes currentNodes = currentState.nodes();
    DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(currentNodes);
    nodesBuilder.masterNodeId(currentState.nodes().getLocalNodeId());
    for (final Task joinTask : joiningNodes) {
        if (joinTask.isBecomeMasterTask()) {
            refreshDiscoveryNodeVersionAfterUpgrade(currentNodes, nodesBuilder);
        } else if (joinTask.isFinishElectionTask()) {
        // no-op
        } else {
            final DiscoveryNode joiningNode = joinTask.node();
            final DiscoveryNode nodeWithSameId = nodesBuilder.get(joiningNode.getId());
            if (nodeWithSameId != null && nodeWithSameId.equals(joiningNode) == false) {
                logger.debug("removing existing node [{}], which conflicts with incoming join from [{}]", nodeWithSameId, joiningNode);
                nodesBuilder.remove(nodeWithSameId.getId());
            }
            final DiscoveryNode nodeWithSameAddress = currentNodes.findByAddress(joiningNode.getAddress());
            if (nodeWithSameAddress != null && nodeWithSameAddress.equals(joiningNode) == false) {
                logger.debug("removing existing node [{}], which conflicts with incoming join from [{}]", nodeWithSameAddress, joiningNode);
                nodesBuilder.remove(nodeWithSameAddress.getId());
            }
        }
    }
    // now trim any left over dead nodes - either left there when the previous master stepped down
    // or removed by us above
    ClusterState tmpState = ClusterState.builder(currentState).nodes(nodesBuilder).blocks(ClusterBlocks.builder().blocks(currentState.blocks()).removeGlobalBlock(NoMasterBlockService.NO_MASTER_BLOCK_ID)).build();
    logger.trace("becomeMasterAndTrimConflictingNodes: {}", tmpState.nodes());
    allocationService.cleanCaches();
    tmpState = PersistentTasksCustomMetadata.disassociateDeadNodes(tmpState);
    return ClusterState.builder(allocationService.disassociateDeadNodes(tmpState, false, "removed dead nodes on election"));
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes)

Example 19 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class JoinTaskExecutor method execute.

@Override
public ClusterTasksResult<Task> execute(ClusterState currentState, List<Task> joiningNodes) throws Exception {
    final ClusterTasksResult.Builder<Task> results = ClusterTasksResult.builder();
    final DiscoveryNodes currentNodes = currentState.nodes();
    boolean nodesChanged = false;
    ClusterState.Builder newState;
    if (joiningNodes.size() == 1 && joiningNodes.get(0).isFinishElectionTask()) {
        return results.successes(joiningNodes).build(currentState);
    } else if (currentNodes.getMasterNode() == null && joiningNodes.stream().anyMatch(Task::isBecomeMasterTask)) {
        assert joiningNodes.stream().anyMatch(Task::isFinishElectionTask) : "becoming a master but election is not finished " + joiningNodes;
        // use these joins to try and become the master.
        // Note that we don't have to do any validation of the amount of joining nodes - the commit
        // during the cluster state publishing guarantees that we have enough
        newState = becomeMasterAndTrimConflictingNodes(currentState, joiningNodes);
        nodesChanged = true;
    } else if (currentNodes.isLocalNodeElectedMaster() == false) {
        logger.trace("processing node joins, but we are not the master. current master: {}", currentNodes.getMasterNode());
        throw new NotMasterException("Node [" + currentNodes.getLocalNode() + "] not master for join request");
    } else {
        newState = ClusterState.builder(currentState);
    }
    DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(newState.nodes());
    assert nodesBuilder.isLocalNodeElectedMaster();
    Version minClusterNodeVersion = newState.nodes().getMinNodeVersion();
    Version maxClusterNodeVersion = newState.nodes().getMaxNodeVersion();
    // we only enforce major version transitions on a fully formed clusters
    final boolean enforceMajorVersion = currentState.getBlocks().hasGlobalBlock(STATE_NOT_RECOVERED_BLOCK) == false;
    // processing any joins
    Map<String, String> joiniedNodeNameIds = new HashMap<>();
    for (final Task joinTask : joiningNodes) {
        if (joinTask.isBecomeMasterTask() || joinTask.isFinishElectionTask()) {
        // noop
        } else if (currentNodes.nodeExistsWithSameRoles(joinTask.node()) && !currentNodes.nodeExistsWithBWCVersion(joinTask.node())) {
            logger.debug("received a join request for an existing node [{}]", joinTask.node());
        } else {
            final DiscoveryNode node = joinTask.node();
            try {
                if (enforceMajorVersion) {
                    ensureMajorVersionBarrier(node.getVersion(), minClusterNodeVersion);
                }
                ensureNodesCompatibility(node.getVersion(), minClusterNodeVersion, maxClusterNodeVersion);
                // we do this validation quite late to prevent race conditions between nodes joining and importing dangling indices
                // we have to reject nodes that don't support all indices we have in this cluster
                ensureIndexCompatibility(node.getVersion(), currentState.getMetadata());
                nodesBuilder.add(node);
                nodesChanged = true;
                minClusterNodeVersion = Version.min(minClusterNodeVersion, node.getVersion());
                maxClusterNodeVersion = Version.max(maxClusterNodeVersion, node.getVersion());
                if (node.isMasterNode()) {
                    joiniedNodeNameIds.put(node.getName(), node.getId());
                }
            } catch (IllegalArgumentException | IllegalStateException e) {
                results.failure(joinTask, e);
                continue;
            }
        }
        results.success(joinTask);
    }
    if (nodesChanged) {
        rerouteService.reroute("post-join reroute", Priority.HIGH, ActionListener.wrap(r -> logger.trace("post-join reroute completed"), e -> logger.debug("post-join reroute failed", e)));
        if (joiniedNodeNameIds.isEmpty() == false) {
            Set<CoordinationMetadata.VotingConfigExclusion> currentVotingConfigExclusions = currentState.getVotingConfigExclusions();
            Set<CoordinationMetadata.VotingConfigExclusion> newVotingConfigExclusions = currentVotingConfigExclusions.stream().map(e -> {
                // Update nodeId in VotingConfigExclusion when a new node with excluded node name joins
                if (CoordinationMetadata.VotingConfigExclusion.MISSING_VALUE_MARKER.equals(e.getNodeId()) && joiniedNodeNameIds.containsKey(e.getNodeName())) {
                    return new CoordinationMetadata.VotingConfigExclusion(joiniedNodeNameIds.get(e.getNodeName()), e.getNodeName());
                } else {
                    return e;
                }
            }).collect(Collectors.toSet());
            // if VotingConfigExclusions did get updated
            if (newVotingConfigExclusions.equals(currentVotingConfigExclusions) == false) {
                CoordinationMetadata.Builder coordMetadataBuilder = CoordinationMetadata.builder(currentState.coordinationMetadata()).clearVotingConfigExclusions();
                newVotingConfigExclusions.forEach(coordMetadataBuilder::addVotingConfigExclusion);
                Metadata newMetadata = Metadata.builder(currentState.metadata()).coordinationMetadata(coordMetadataBuilder.build()).build();
                return results.build(allocationService.adaptAutoExpandReplicas(newState.nodes(nodesBuilder).metadata(newMetadata).build()));
            }
        }
        return results.build(allocationService.adaptAutoExpandReplicas(newState.nodes(nodesBuilder).build()));
    } else {
        // for the joining node to finalize its join and set us as a master
        return results.build(newState.build());
    }
}
Also used : DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) STATE_NOT_RECOVERED_BLOCK(org.opensearch.gateway.GatewayService.STATE_NOT_RECOVERED_BLOCK) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) Version(org.opensearch.Version) Priority(org.opensearch.common.Priority) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) LegacyESVersion(org.opensearch.LegacyESVersion) Map(java.util.Map) NotMasterException(org.opensearch.cluster.NotMasterException) RerouteService(org.opensearch.cluster.routing.RerouteService) BiConsumer(java.util.function.BiConsumer) ActionListener(org.opensearch.action.ActionListener) ClusterBlocks(org.opensearch.cluster.block.ClusterBlocks) Collection(java.util.Collection) PersistentTasksCustomMetadata(org.opensearch.persistent.PersistentTasksCustomMetadata) Set(java.util.Set) ClusterStateTaskExecutor(org.opensearch.cluster.ClusterStateTaskExecutor) Settings(org.opensearch.common.settings.Settings) TransportService(org.opensearch.transport.TransportService) Collectors(java.util.stream.Collectors) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Collections(java.util.Collections) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) HashMap(java.util.HashMap) Metadata(org.opensearch.cluster.metadata.Metadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) PersistentTasksCustomMetadata(org.opensearch.persistent.PersistentTasksCustomMetadata) Version(org.opensearch.Version) LegacyESVersion(org.opensearch.LegacyESVersion) NotMasterException(org.opensearch.cluster.NotMasterException) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes)

Example 20 with DiscoveryNode

use of org.opensearch.cluster.node.DiscoveryNode in project OpenSearch by opensearch-project.

the class Coordinator method validVotingConfigExclusionState.

/*
    * Valid Voting Configuration Exclusion state criteria:
    * 1. Every voting config exclusion with an ID of _absent_ should not match any nodes currently in the cluster by name
    * 2. Every voting config exclusion with a name of _absent_ should not match any nodes currently in the cluster by ID
     */
static boolean validVotingConfigExclusionState(ClusterState clusterState) {
    Set<VotingConfigExclusion> votingConfigExclusions = clusterState.getVotingConfigExclusions();
    Set<String> nodeNamesWithAbsentId = votingConfigExclusions.stream().filter(e -> e.getNodeId().equals(VotingConfigExclusion.MISSING_VALUE_MARKER)).map(VotingConfigExclusion::getNodeName).collect(Collectors.toSet());
    Set<String> nodeIdsWithAbsentName = votingConfigExclusions.stream().filter(e -> e.getNodeName().equals(VotingConfigExclusion.MISSING_VALUE_MARKER)).map(VotingConfigExclusion::getNodeId).collect(Collectors.toSet());
    for (DiscoveryNode node : clusterState.getNodes()) {
        if (node.isMasterNode() && (nodeIdsWithAbsentName.contains(node.getId()) || nodeNamesWithAbsentId.contains(node.getName()))) {
            return false;
        }
    }
    return true;
}
Also used : VotingConfigExclusion(org.opensearch.cluster.coordination.CoordinationMetadata.VotingConfigExclusion) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode)

Aggregations

DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)673 ClusterState (org.opensearch.cluster.ClusterState)164 Settings (org.opensearch.common.settings.Settings)152 ArrayList (java.util.ArrayList)137 DiscoveryNodes (org.opensearch.cluster.node.DiscoveryNodes)123 ThreadPool (org.opensearch.threadpool.ThreadPool)103 ClusterService (org.opensearch.cluster.service.ClusterService)100 CountDownLatch (java.util.concurrent.CountDownLatch)98 HashSet (java.util.HashSet)93 TransportService (org.opensearch.transport.TransportService)92 IOException (java.io.IOException)89 ActionListener (org.opensearch.action.ActionListener)88 Matchers.containsString (org.hamcrest.Matchers.containsString)84 ClusterName (org.opensearch.cluster.ClusterName)82 Version (org.opensearch.Version)80 List (java.util.List)78 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)78 HashMap (java.util.HashMap)77 TimeValue (org.opensearch.common.unit.TimeValue)77 ShardId (org.opensearch.index.shard.ShardId)76