diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java index 3c2c09b..1977e46 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceTrackerService.java @@ -460,7 +460,9 @@ public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request) RMNodeStatusEvent nodeStatusEvent = new RMNodeStatusEvent(nodeId, remoteNodeStatus.getNodeHealthStatus(), remoteNodeStatus.getContainersStatuses(), - remoteNodeStatus.getKeepAliveApplications(), nodeHeartBeatResponse); + remoteNodeStatus.getKeepAliveApplications(), + remoteNodeStatus.getContainersUtilization(), + remoteNodeStatus.getNodeUtilization(), nodeHeartBeatResponse); if (request.getLogAggregationReportsForApps() != null && !request.getLogAggregationReportsForApps().isEmpty()) { nodeStatusEvent.setLogAggregationReportsForApps(request diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java index 0386be6..371077d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNode.java @@ -29,6 +29,7 @@ import org.apache.hadoop.yarn.api.records.NodeState; import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; +import org.apache.hadoop.yarn.server.api.records.ResourceUtilization; /** * Node managers information on available resources @@ -100,7 +101,19 @@ * @return the total available resource. */ public Resource getTotalCapability(); - + + /** + * the total resource utilization of the containers. + * @return the total resource utilization of the containers. + */ + public ResourceUtilization getContainersUtilization(); + + /** + * the total resource utilization of the node. + * @return the total resource utilization of the node. + */ + public ResourceUtilization getNodeUtilization(); + /** * The rack name for this node manager. * @return the rack name. diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java index f182d02..e2dd5a6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeImpl.java @@ -51,6 +51,7 @@ import org.apache.hadoop.yarn.server.api.protocolrecords.NMContainerStatus; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.ResourceUtilization; import org.apache.hadoop.yarn.server.resourcemanager.ClusterMetrics; import org.apache.hadoop.yarn.server.resourcemanager.NodesListManagerEvent; import org.apache.hadoop.yarn.server.resourcemanager.NodesListManagerEventType; @@ -108,6 +109,11 @@ private long lastHealthReportTime; private String nodeManagerVersion; + /* Aggregated resource utilization for the containers. */ + private ResourceUtilization containersUtilization; + /* Resource utilization for the node. */ + private ResourceUtilization nodeUtilization; + private final ContainerAllocationExpirer containerAllocationExpirer; /* set of containers that have just launched */ private final Set launchedContainers = @@ -369,6 +375,49 @@ public String getNodeManagerVersion() { } @Override + public ResourceUtilization getContainersUtilization() { + this.readLock.lock(); + + try { + return this.containersUtilization; + } finally { + this.readLock.unlock(); + } + } + + public void setContainersUtilization( + ResourceUtilization containersUtilization) { + this.writeLock.lock(); + + try { + this.containersUtilization = containersUtilization; + } finally { + this.writeLock.unlock(); + } + } + + @Override + public ResourceUtilization getNodeUtilization() { + this.readLock.lock(); + + try { + return this.nodeUtilization; + } finally { + this.readLock.unlock(); + } + } + + public void setNodeUtilization(ResourceUtilization nodeUtilization) { + this.writeLock.lock(); + + try { + this.nodeUtilization = nodeUtilization; + } finally { + this.writeLock.unlock(); + } + } + + @Override public NodeState getState() { this.readLock.lock(); @@ -805,6 +854,8 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); + rmNode.setContainersUtilization(statusEvent.getContainersUtilization()); + rmNode.setNodeUtilization(statusEvent.getNodeUtilization()); if (!remoteNodeHealthStatus.getIsNodeHealthy()) { LOG.info("Node " + rmNode.nodeId + " reported UNHEALTHY with details: " + remoteNodeHealthStatus.getHealthReport()); @@ -860,6 +911,8 @@ public NodeState transition(RMNodeImpl rmNode, RMNodeEvent event) { rmNode.setHealthReport(remoteNodeHealthStatus.getHealthReport()); rmNode.setLastHealthReportTime( remoteNodeHealthStatus.getLastHealthReportTime()); + rmNode.setContainersUtilization(statusEvent.getContainersUtilization()); + rmNode.setNodeUtilization(statusEvent.getNodeUtilization()); if (remoteNodeHealthStatus.getIsNodeHealthy()) { rmNode.context.getDispatcher().getEventHandler().handle( new NodeAddedSchedulerEvent(rmNode)); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java index b95d7d3..7fdafcc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmnode/RMNodeStatusEvent.java @@ -25,6 +25,7 @@ import org.apache.hadoop.yarn.server.api.protocolrecords.LogAggregationReport; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; import org.apache.hadoop.yarn.server.api.records.NodeHealthStatus; +import org.apache.hadoop.yarn.server.api.records.ResourceUtilization; public class RMNodeStatusEvent extends RMNodeEvent { @@ -32,27 +33,31 @@ private final List containersCollection; private final NodeHeartbeatResponse latestResponse; private final List keepAliveAppIds; + private final ResourceUtilization containersUtilization; + private final ResourceUtilization nodeUtilization; private List logAggregationReportsForApps; public RMNodeStatusEvent(NodeId nodeId, NodeHealthStatus nodeHealthStatus, List collection, List keepAliveAppIds, + ResourceUtilization containersUtilization, + ResourceUtilization nodeUtilization, NodeHeartbeatResponse latestResponse) { - super(nodeId, RMNodeEventType.STATUS_UPDATE); - this.nodeHealthStatus = nodeHealthStatus; - this.containersCollection = collection; - this.keepAliveAppIds = keepAliveAppIds; - this.latestResponse = latestResponse; - this.logAggregationReportsForApps = null; + this(nodeId, nodeHealthStatus, collection, keepAliveAppIds, + containersUtilization, nodeUtilization, latestResponse, null); } public RMNodeStatusEvent(NodeId nodeId, NodeHealthStatus nodeHealthStatus, List collection, List keepAliveAppIds, + ResourceUtilization containersUtilization, + ResourceUtilization nodeUtilization, NodeHeartbeatResponse latestResponse, List logAggregationReportsForApps) { super(nodeId, RMNodeEventType.STATUS_UPDATE); this.nodeHealthStatus = nodeHealthStatus; this.containersCollection = collection; this.keepAliveAppIds = keepAliveAppIds; + this.containersUtilization = containersUtilization; + this.nodeUtilization = nodeUtilization; this.latestResponse = latestResponse; this.logAggregationReportsForApps = logAggregationReportsForApps; } @@ -73,6 +78,14 @@ public NodeHeartbeatResponse getLatestResponse() { return this.keepAliveAppIds; } + public ResourceUtilization getContainersUtilization() { + return this.containersUtilization; + } + + public ResourceUtilization getNodeUtilization() { + return this.nodeUtilization; + } + public List getLogAggregationReportsForApps() { return this.logAggregationReportsForApps; } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/SchedulerNode.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/SchedulerNode.java index f03663a..1faa1c1 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/SchedulerNode.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/SchedulerNode.java @@ -35,6 +35,7 @@ import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; +import org.apache.hadoop.yarn.server.api.records.ResourceUtilization; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerState; @@ -58,6 +59,10 @@ private Resource totalResourceCapability; private RMContainer reservedContainer; private volatile int numContainers; + private ResourceUtilization containersUtilization = + ResourceUtilization.newInstance(0, 0, 0f); + private ResourceUtilization nodeUtilization = + ResourceUtilization.newInstance(0, 0, 0f); /* set of containers that are allocated containers */ @@ -308,4 +313,41 @@ public String getPartition() { return this.labels.iterator().next(); } } + + /** + * Set the resource utilization of the containers in the node. + * @param containersUtilization Resource utilization of the containers. + */ + public void setContainersUtilization( + ResourceUtilization containersUtilization) { + if (containersUtilization != null) { + this.containersUtilization = containersUtilization; + } + } + + /** + * Get the resource utilization of the containers in the node. + * @return Resource utilization of the containers. + */ + public ResourceUtilization getContainersUtilization() { + return this.containersUtilization; + } + + /** + * Set the resource utilization of the node. This includes the containers. + * @param containersUtilization Resource utilization of the node. + */ + public void setNodeUtilization(ResourceUtilization nodeUtilization) { + if (nodeUtilization != null) { + this.nodeUtilization = nodeUtilization; + } + } + + /** + * Get the resource utilization of the node. + * @return Resource utilization of the node. + */ + public ResourceUtilization getNodeUtilization() { + return this.nodeUtilization; + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java index b4b1383..73c48c5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java @@ -1013,6 +1013,10 @@ private synchronized void nodeUpdate(RMNode nm) { releaseResources); schedulerHealth.updateSchedulerReleaseCounts(releasedContainers); + // Updating node resource utilization + node.setContainersUtilization(nm.getContainersUtilization()); + node.setNodeUtilization(nm.getNodeUtilization()); + // Now node data structures are upto date and ready for scheduling. if(LOG.isDebugEnabled()) { LOG.debug("Node being looked for scheduling " + nm