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 7a1ba74..0b47e25 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 @@ -60,6 +60,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppRunningOnNodeEvent; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.ContainerAllocationExpirer; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerResourceReleasedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeAddedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeResourceUpdateSchedulerEvent; @@ -930,6 +931,13 @@ private void handleContainerStatus(List containerStatuses) { for (ContainerStatus remoteContainer : containerStatuses) { ContainerId containerId = remoteContainer.getContainerId(); + if (remoteContainer.getState() == ContainerState.COMPLETE) { + // Released container's resource + context.getDispatcher().getEventHandler().handle( + new ContainerResourceReleasedSchedulerEvent( + remoteContainer.getContainerId(), nodeId)); + } + // Don't bother with containers already scheduled for cleanup, or for // applications already killed. The scheduler doens't need to know any // more about this container 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..139b0cb 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 @@ -200,20 +200,27 @@ private synchronized void updateResource(Container container) { /** * Release an allocated container on this node. * - * @param container - * container to be released + * @param containerId + * containerId to be released */ - public synchronized void releaseContainer(Container container) { - if (!isValidContainer(container.getId())) { - LOG.error("Invalid container released " + container); + public synchronized void releaseContainer(ContainerId containerId) { + if (!isValidContainer(containerId)) { + LOG.error("Invalid container released " + containerId); return; } - /* remove the containers from the nodemanger */ - if (null != launchedContainers.remove(container.getId())) { - updateResource(container); + RMContainer rmContainer = launchedContainers.remove(containerId); + if (rmContainer == null) { + if (LOG.isDebugEnabled()) { + LOG.debug(containerId + "'s resource has already been released"); + } + return; } + Container container = rmContainer.getContainer(); + /* remove the containers from the nodemanger */ + updateResource(container); + LOG.info("Released container " + container.getId() + " of capacity " + container.getResource() + " on host " + rmNode.getNodeAddress() + ", which currently has " + numContainers + " containers, " 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 dbaccaf..0279a2e 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 @@ -110,6 +110,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.AppRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerExpiredSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerRescheduledEvent; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerResourceReleasedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeAddedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeLabelsUpdateSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeRemovedSchedulerEvent; @@ -1370,6 +1371,17 @@ public void handle(SchedulerEvent event) { recoverResourceRequestForContainer(container); } break; + case CONTAINER_RESOURCE_RELEASED: + { + ContainerResourceReleasedSchedulerEvent + containerResourceReleasedSchedulerEvent = + (ContainerResourceReleasedSchedulerEvent) event; + FiCaSchedulerNode node = getNode( + containerResourceReleasedSchedulerEvent.getNodeId()); + node.releaseContainer( + containerResourceReleasedSchedulerEvent.getContainerId()); + } + break; default: LOG.error("Invalid eventtype " + event.getType() + ". Ignoring!"); } 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/LeafQueue.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/LeafQueue.java index b43f658..1af1954 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/LeafQueue.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/LeafQueue.java @@ -1112,8 +1112,6 @@ public void completedContainer(Resource clusterResource, removed = application.containerCompleted(rmContainer, containerStatus, event, node.getPartition()); - - node.releaseContainer(container); } // Book-keeping 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/event/SchedulerEventType.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/ContainerResourceReleasedSchedulerEvent.java similarity index 58% copy from hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/SchedulerEventType.java copy to hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/ContainerResourceReleasedSchedulerEvent.java index 40dd66b..71d7ffd 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/SchedulerEventType.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/ContainerResourceReleasedSchedulerEvent.java @@ -18,31 +18,25 @@ package org.apache.hadoop.yarn.server.resourcemanager.scheduler.event; -public enum SchedulerEventType { - - // Source: Node - NODE_ADDED, - NODE_REMOVED, - NODE_UPDATE, - NODE_RESOURCE_UPDATE, - NODE_LABELS_UPDATE, - - // Source: RMApp - APP_ADDED, - APP_REMOVED, - - // Source: RMAppAttempt - APP_ATTEMPT_ADDED, - APP_ATTEMPT_REMOVED, - - // Source: ContainerAllocationExpirer - CONTAINER_EXPIRED, - - // Source: RMContainer - CONTAINER_RESCHEDULED, - - // Source: SchedulingEditPolicy - DROP_RESERVATION, - PREEMPT_CONTAINER, - KILL_CONTAINER +import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.hadoop.yarn.api.records.NodeId; + +public class ContainerResourceReleasedSchedulerEvent extends SchedulerEvent { + private ContainerId containerId; + private NodeId nodeId; + + public ContainerResourceReleasedSchedulerEvent(ContainerId containerId, + NodeId nodeId) { + super(SchedulerEventType.CONTAINER_RESOURCE_RELEASED); + this.containerId = containerId; + this.nodeId = nodeId; + } + + public ContainerId getContainerId() { + return containerId; + } + + public NodeId getNodeId() { + return nodeId; + } } 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/event/SchedulerEventType.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/SchedulerEventType.java index 40dd66b..dd16570 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/SchedulerEventType.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/event/SchedulerEventType.java @@ -26,6 +26,7 @@ NODE_UPDATE, NODE_RESOURCE_UPDATE, NODE_LABELS_UPDATE, + CONTAINER_RESOURCE_RELEASED, // Source: RMApp APP_ADDED, 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/fair/FairScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java index 3a39799..1210761 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java @@ -77,6 +77,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.AppRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerExpiredSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerRescheduledEvent; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerResourceReleasedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeAddedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeResourceUpdateSchedulerEvent; @@ -835,7 +836,6 @@ protected synchronized void completedContainer(RMContainer rmContainer, application.unreserve(rmContainer.getReservedPriority(), node); } else { application.containerCompleted(rmContainer, containerStatus, event); - node.releaseContainer(container); updateRootQueueMetrics(); } @@ -1259,6 +1259,18 @@ public void handle(SchedulerEvent event) { RMContainer container = containerRescheduledEvent.getContainer(); recoverResourceRequestForContainer(container); break; + case CONTAINER_RESOURCE_RELEASED: + if (!(event instanceof ContainerResourceReleasedSchedulerEvent)) { + throw new RuntimeException("Unexpected event type: " + event); + } + ContainerResourceReleasedSchedulerEvent + containerResourceReleasedSchedulerEvent = + (ContainerResourceReleasedSchedulerEvent)event; + FSSchedulerNode node = getFSSchedulerNode( + containerResourceReleasedSchedulerEvent.getNodeId()); + node.releaseContainer( + containerResourceReleasedSchedulerEvent.getContainerId()); + break; default: LOG.error("Unknown event arrived at FairScheduler: " + event.toString()); } 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/fifo/FifoScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fifo/FifoScheduler.java index 99760df..60c8c49 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fifo/FifoScheduler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fifo/FifoScheduler.java @@ -86,6 +86,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.AppRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerExpiredSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerRescheduledEvent; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.ContainerResourceReleasedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeAddedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeRemovedSchedulerEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeResourceUpdateSchedulerEvent; @@ -868,6 +869,17 @@ public void handle(SchedulerEvent event) { recoverResourceRequestForContainer(container); } break; + case CONTAINER_RESOURCE_RELEASED: + { + ContainerResourceReleasedSchedulerEvent + containerResourceReleasedSchedulerEvent = + (ContainerResourceReleasedSchedulerEvent) event; + FiCaSchedulerNode node = getNode( + containerResourceReleasedSchedulerEvent.getNodeId()); + node.releaseContainer( + containerResourceReleasedSchedulerEvent.getContainerId()); + } + break; default: LOG.error("Invalid eventtype " + event.getType() + ". Ignoring!"); } @@ -903,9 +915,6 @@ protected synchronized void completedContainer(RMContainer rmContainer, // Inform the application application.containerCompleted(rmContainer, containerStatus, event, RMNodeLabelsManager.NO_LABEL); - - // Inform the node - node.releaseContainer(container); // Update total usage Resources.subtractFrom(usedResource, container.getResource()); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestChildQueueOrder.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestChildQueueOrder.java index 9dcab2e..4fd2830 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestChildQueueOrder.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestChildQueueOrder.java @@ -157,7 +157,7 @@ public CSAssignment answer(InvocationOnMock invocation) throws Throwable { }). when(queue).assignContainers(eq(clusterResource), eq(node), any(ResourceLimits.class), any(SchedulingMode.class)); - doNothing().when(node).releaseContainer(any(Container.class)); + doNothing().when(node).releaseContainer(any(ContainerId.class)); } @@ -228,7 +228,7 @@ public void testSortedQueues() throws Exception { FiCaSchedulerNode node_0 = TestUtils.getMockNode("host_0", DEFAULT_RACK, 0, memoryPerNode*GB); - doNothing().when(node_0).releaseContainer(any(Container.class)); + doNothing().when(node_0).releaseContainer(any(ContainerId.class)); final Resource clusterResource = Resources.createResource(numNodes * (memoryPerNode*GB),