[
https://issues.apache.org/jira/browse/YARN-11730?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17882304#comment-17882304
]
ASF GitHub Bot commented on YARN-11730:
---------------------------------------
slfan1989 commented on code in PR #7049:
URL: https://github.com/apache/hadoop/pull/7049#discussion_r1762632209
##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/NodesListManager.java:
##########
@@ -387,6 +388,115 @@ private void handleExcludeNodeList(boolean graceful, int
timeout) {
updateInactiveNodes();
}
+ /**
+ * Marks the unregistered nodes as LOST
+ * if the feature is enabled via a configuration flag.
+ *
+ * This method finds nodes that are present in the include list but are not
+ * registered with the ResourceManager. Such nodes are then marked as LOST.
+ *
+ * The steps are as follows:
+ * 1. Retrieve all hostnames of registered nodes from RM.
+ * 2. Identify the nodes present in the include list but are not registered
+ * 3. Remove nodes from the exclude list
+ * 4. Dispatch LOST events for filtered nodes to mark them as LOST.
+ *
+ * @param yarnConf Configuration object that holds the YARN configurations.
+ */
+ private void markUnregisteredNodesAsLost(Configuration yarnConf) {
+ // Check if tracking unregistered nodes is enabled in the configuration
+ if
(!yarnConf.getBoolean(YarnConfiguration.ENABLE_TRACKING_FOR_UNREGISTERED_NODES,
+ YarnConfiguration.DEFAULT_ENABLE_TRACKING_FOR_UNREGISTERED_NODES)) {
+ LOG.debug("Unregistered node tracking is disabled. " +
+ "Skipping marking unregistered nodes as LOST.");
+ return;
+ }
+
+ // Set to store all registered hostnames from both active and inactive
lists
+ Set<String> registeredHostNames = gatherRegisteredHostNames();
+ // Event handler to dispatch LOST events
+ EventHandler eventHandler =
this.rmContext.getDispatcher().getEventHandler();
+
+ // Identify nodes that are in the include list but are not registered
+ // and are not in the exclude list
+ List<String> nodesToMarkLost = new ArrayList<>();
+ HostDetails hostDetails = hostsReader.getHostDetails();
+ Set<String> includes = hostDetails.getIncludedHosts();
+ Set<String> excludes = hostDetails.getExcludedHosts();
+
+ for (String includedNode : includes) {
+ if (!registeredHostNames.contains(includedNode) &&
!excludes.contains(includedNode)) {
+ LOG.info("Lost node: " + includedNode);
+ nodesToMarkLost.add(includedNode);
+ }
+ }
+
+ // Dispatch LOST events for the identified lost nodes
+ for (String lostNode : nodesToMarkLost) {
+ dispatchLostEvent(eventHandler, lostNode);
+ }
+
+ // Log successful completion of marking unregistered nodes as LOST
+ LOG.info("Successfully marked unregistered nodes as LOST");
+ }
+
+ /**
+ * Gathers all registered hostnames from both active and inactive RMNodes.
+ *
+ * @return A set of registered hostnames.
+ */
+ private Set<String> gatherRegisteredHostNames() {
+ Set<String> registeredHostNames = new HashSet<>();
+ LOG.info("Getting all the registered hostnames");
+
+ // Gather all registered nodes (active) from RM into the set
+ for (RMNode node : this.rmContext.getRMNodes().values()) {
+ registeredHostNames.add(node.getHostName());
+ }
+
+ // Gather all inactive nodes from RM into the set
+ for (RMNode node : this.rmContext.getInactiveRMNodes().values()) {
+ registeredHostNames.add(node.getHostName());
+ }
+
+ return registeredHostNames;
+ }
+
+ /**
+ * Dispatches a LOST event for a specified lost node.
+ *
+ * @param eventHandler The EventHandler used to dispatch the LOST event.
+ * @param lostNode The hostname of the lost node for which the event is
+ * being dispatched.
+ */
+ private void dispatchLostEvent(EventHandler eventHandler, String lostNode) {
+ // Generate a NodeId for the lost node with a special port -2
+ NodeId nodeId = createLostNodeId(lostNode);
+ RMNodeEvent lostEvent = new RMNodeEvent(nodeId, RMNodeEventType.EXPIRE);
+ RMNodeImpl rmNode = new RMNodeImpl(nodeId, this.rmContext, lostNode, -2,
-2,
+ new UnknownNode(lostNode), Resource.newInstance(0, 0), "unknown");
+
+ try {
+ // Dispatch the LOST event to signal the node is no longer active
+ eventHandler.handle(lostEvent);
+
+ // After successful dispatch, update the node status in RMContext
+ // Set the node's timestamp for when it became untracked
+ rmNode.setUntrackedTimeStamp(Time.monotonicNow());
+
+ // Add the node to the active and inactive node maps in RMContext
+ this.rmContext.getRMNodes().put(nodeId, rmNode);
+ this.rmContext.getInactiveRMNodes().put(nodeId, rmNode);
+
+ LOG.info("Successfully dispatched LOST event and deactivated node: "
Review Comment:
We use {} to record logs.
```
LOG.info("Successfully dispatched LOST event and deactivated node: {}, Node
ID: {}",
lostNode, nodeId);
```
> Resourcemanager node reporting enhancement for unregistered hosts
> -----------------------------------------------------------------
>
> Key: YARN-11730
> URL: https://issues.apache.org/jira/browse/YARN-11730
> Project: Hadoop YARN
> Issue Type: Improvement
> Components: resourcemanager, yarn
> Affects Versions: 3.4.0
> Environment: Tested on multiple environments:
> A. Docker Environment{*}:{*}
> * Base OS: *Ubuntu 20.04*
> * *Java 8* installed from OpenJDK.
> * Docker image includes Hadoop binaries, user configurations, and ports for
> YARN services.
> * Verified behavior using a Hadoop snapshot in a containerized environment.
> * Performed Namenode formatting and validated service interactions through
> exposed ports.
> * Repo reference:
> [arjunmohnot/hadoop-yarn-docker|https://github.com/arjunmohnot/hadoop-yarn-docker/tree/main]
> B. Bare-metal Distributed Setup (RedHat Linux){*}:{*}
> * Running *Java 8* in a High-Availability (HA) configuration with
> *Zookeeper* for locking mechanism.
> * Two ResourceManagers (RM) in HA: Failover tested between HA1 and HA2 RM
> node, including state retention and proper node state transitions.
> * Verified node state transitions during RM failover, ensuring nodes moved
> between LOST, ACTIVE, and other states as expected.
> Reporter: Arjun Mohnot
> Priority: Major
> Labels: pull-request-available
> Fix For: 3.5.0
>
>
> h3. Issue Overview
> When the ResourceManager (RM) starts, nodes listed in the _"include"_ file
> are not immediately reported until their corresponding NodeManagers (NMs)
> send their first heartbeat. However, nodes in the _"exclude"_ file are
> instantly reflected in the _"Decommissioned Hosts"_ section with a port value
> -1.
> This design creates several challenges:
> * {*}Untracked Nodemanagers{*}: During Resourcemanager HA failover or RM
> standalone restart, some nodes may not report back, even though they are
> listed in the _"include"_ file. These nodes neither appear in the _LOST_
> state nor are they represented in the RM's JMX metrics. This results in an
> untracked state, making it difficult to monitor their status. While in HDFS
> similar behaviour exists and is marked as {_}"DEAD"{_}.
> * {*}Monitoring Gaps{*}: Nodes in the _"include"_ file are not visible until
> they send their first heartbeat. This delay impacts real-time cluster
> monitoring, leading to a lack of immediate visibility for these nodes in
> Resourcemanager's state on the total no. of nodes.
> * {*}Operational Impact{*}: These unreported nodes cause operational
> difficulties, particularly in automated workflows such as OS Upgrade
> Automation (OSUA), node recovery automation, and others where validation
> depends on nodes being reflected in JMX as {_}LOST{_}, {_}UNHEALTHY{_}, or
> {_}DECOMMISSIONED, etc{_}. Nodes that don't report, however, require hacky
> workarounds to determine their accurate status.
> h3. Proposed Solution
> To address these issues, we propose automatically assigning the _LOST_ state
> to any node listed in the _"include"_ file that are not registered and not
> part of the exclude file by default at the RM startup or HA failover. This
> can be done by marking the node with a special port value {_}-2{_}, signaling
> that the node is considered LOST but has not yet been reported. Whenever a
> heartbeat is received for that {color:#de350b}nodeID{color}, it will be
> transitioned from _LOST_ to {_}RUNNING{_}, {_}UNHEALTHY{_}, or any other
> required desired state.
> h3. Key implementation points
> * Mark Unreported Nodes as LOST: Nodes in the _"include"_ file not part of
> the RM active node context should be automatically marked as {_}LOST{_}. This
> can be achieved by modifying the _NodesListManager_ under the
> {color:#de350b}refreshHostsReader{color} method, invoked during failover, or
> manual node refresh operations. This logic should ensure that all
> unregistered nodes are moved to the _LOST_ state, with port _-2_ indicating
> the node is untracked.
> * For non-HA setups, this process can be triggered during RM service startup
> to mark nodes as _LOST_ initially, and they will gradually transition to
> their desired state when the heartbeat is received.
> * Handle Node Heartbeat and Transition: When a node sends its first
> heartbeat, the system should verify if the node is listed in
> {color:#de350b}getInactiveRMNodes(){color}. If the node exists in the _LOST_
> state, the RM should remove it from the inactive list, decrement the _LOST_
> node count, and handle the transition back to the active node set.
> * This logic can be placed in the state transition method within
> {color:#de350b}RMNodeImpl.java{color}, ensuring that nodes transitioned from
> _NEW_ to _LOST_ state, and recover gracefully from the _LOST_ state upon
> receiving their heartbeat.
> h3. Benefits
> * {*}Improved Cluster Monitoring{*}: Automatically assigning a _LOST_ state
> to nodes listed in the _"include"_ file but not reporting ensures that every
> node in the cluster has a well-defined state ({_}ACTIVE{_}, {_}LOST{_},
> {_}DECOMMISSIONED{_}, {_}UNHEALTHY, etc{_}). This eliminates any potential
> gaps in cluster node visibility and simplifies operational monitoring.
> * {*}Better Recovery Management{*}: By marking unreported nodes as
> {_}LOST{_}, automation can quickly identify which nodes require attention
> during recovery efforts to restore cluster health. This prevents confusion
> between unreachable nodes and untracked nodes, improving recovery accuracy.
> * {*}Enhanced Cluster Stability{*}: This approach improves overall stability
> by preventing nodes from slipping into an untracked or unknown state. It
> guarantees that the system remains aware of all nodes, reducing issues during
> RM failover or restart scenarios.
> h3. Additional Considerations
> * Feature Flag Control: This feature will be enabled/disabled via a
> configuration flag, allowing users to adjust behavior based on their
> requirements. By default, it is marked as {_}False{_}.
> * Enough Validations: The approach has been well-tested on non-HA and HA
> setups, and a dummy docker-based
> [setup|https://github.com/arjunmohnot/hadoop-yarn-docker/tree/main] has been
> created to replicate the behavior. Added the required unit test cases to
> validate the code behavior. Demo
> [video|https://drive.google.com/file/d/1okiPe7uMNVMRUnNYtz-B8Igf8FMGr-SJ/view?usp=sharing]
> for this change.
>
> Any thoughts/suggestions/feedback are welcome!
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]