You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mapreduce-commits@hadoop.apache.org by ac...@apache.org on 2011/05/24 23:15:36 UTC

svn commit: r1127293 - in /hadoop/mapreduce/branches/MR-279: ./ yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/...

Author: acmurthy
Date: Tue May 24 21:15:35 2011
New Revision: 1127293

URL: http://svn.apache.org/viewvc?rev=1127293&view=rev
Log:
Added metrics for tracking reservations in CapacityScheduler. Contributed by Luke Lu.

Modified:
    hadoop/mapreduce/branches/MR-279/CHANGES.txt
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ApplicationMasterService.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/resourcetracker/NodeInfo.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/Application.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/NodeManagerImpl.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/QueueMetrics.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestQueueMetrics.java

Modified: hadoop/mapreduce/branches/MR-279/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/CHANGES.txt?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/CHANGES.txt (original)
+++ hadoop/mapreduce/branches/MR-279/CHANGES.txt Tue May 24 21:15:35 2011
@@ -4,6 +4,9 @@ Trunk (unreleased changes)
 
   MAPREDUCE-279
 
+    Added metrics for tracking reservations in CapacityScheduler. (Luke Lu via
+    acmurthy)
+
     Fix queue refresh to correctly record newly added queues in
     CapacityScheduler. (acmurthy)
 

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ApplicationMasterService.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ApplicationMasterService.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ApplicationMasterService.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ApplicationMasterService.java Tue May 24 21:15:35 2011
@@ -72,7 +72,8 @@ AMRMProtocol, EventHandler<ASMEvent<Appl
   private InetSocketAddress masterServiceAddress;
   private Server server;
   private final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null);
-  private Map<ApplicationId, AMResponse> responseMap = new HashMap<ApplicationId, AMResponse>();
+  private final Map<ApplicationId, AMResponse> responseMap =
+      new HashMap<ApplicationId, AMResponse>();
   private final AMResponse reboot = recordFactory.newRecordInstance(AMResponse.class);
   private final RMContext asmContext;
   
@@ -97,6 +98,7 @@ AMRMProtocol, EventHandler<ASMEvent<Appl
     super.init(conf);
   }
 
+  @Override
   public void start() {
     YarnRPC rpc = YarnRPC.create(getConfig());
     Configuration serverConf = new Configuration(getConfig());
@@ -202,7 +204,6 @@ AMRMProtocol, EventHandler<ASMEvent<Appl
         break;
       case EXPIRE:
         responseMap.remove(id);
-      default: 
         break;
       }
     }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java Tue May 24 21:15:35 2011
@@ -26,6 +26,7 @@ import org.apache.avro.AvroRuntimeExcept
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
 import org.apache.hadoop.security.SecurityUtil;
 import org.apache.hadoop.util.ReflectionUtils;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
@@ -72,7 +73,7 @@ public class ResourceManager extends Com
   private ClientRMService clientRM;
   private ApplicationMasterService masterService;
   private AdminService adminService;
-  private AtomicBoolean shutdown = new AtomicBoolean(false);
+  private final AtomicBoolean shutdown = new AtomicBoolean(false);
   private WebApp webApp;
   private RMContext rmContext;
   private final Store store;
@@ -174,6 +175,8 @@ public class ResourceManager extends Com
       YarnConfiguration.DEFAULT_RM_WEBAPP_BIND_ADDRESS)).
     start(new RMWebApp(this));
 
+    DefaultMetricsSystem.initialize("ResourceManager");
+
     super.start();
 
     synchronized(shutdown) {
@@ -202,6 +205,9 @@ public class ResourceManager extends Com
       shutdown.set(true);
       shutdown.notifyAll();
     }
+
+    DefaultMetricsSystem.shutdown();
+
     super.stop();
   }
   

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/resourcetracker/NodeInfo.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/resourcetracker/NodeInfo.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/resourcetracker/NodeInfo.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/resourcetracker/NodeInfo.java Tue May 24 21:15:35 2011
@@ -100,6 +100,8 @@ public interface NodeInfo {
    */
   public Application getReservedApplication();
 
+  Resource getReservedResource();
+
   public void reserveResource(Application application, Priority priority, 
       Resource resource);
 

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/Application.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/Application.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/Application.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/Application.java Tue May 24 21:15:35 2011
@@ -483,6 +483,7 @@ public class Application {
     LOG.info("Application " + applicationId + " reserved " + resource
         + " on node " + node + ", currently has " + reservedNodes.size()
         + " at priority " + priority);
+    queue.getMetrics().reserveResource(user, resource);
   }
 
   public synchronized void unreserveResource(NodeInfo node, Priority priority) {
@@ -495,6 +496,7 @@ public class Application {
     LOG.info("Application " + applicationId + " unreserved " + " on node "
         + node + ", currently has " + reservedNodes.size() + " at priority "
         + priority);
+    queue.getMetrics().unreserveResource(user, node.getReservedResource());
   }
 
   public synchronized boolean isReserved(NodeInfo node, Priority priority) {
@@ -512,7 +514,7 @@ public class Application {
   }
 
   synchronized public void finish() {
-    // GC pending resources metrics
+    // clear pending resources metrics for the application
     QueueMetrics metrics = queue.getMetrics();
     for (Map<String, ResourceRequest> asks : requests.values()) {
       ResourceRequest request = asks.get(NodeManager.ANY);
@@ -522,6 +524,7 @@ public class Application {
                 .getNumContainers()));
       }
     }
+    metrics.finishApp(this);
   }
 
   public Map<Priority, Set<NodeInfo>> getAllReservations() {

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/NodeManagerImpl.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/NodeManagerImpl.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/NodeManagerImpl.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/NodeManagerImpl.java Tue May 24 21:15:35 2011
@@ -327,6 +327,7 @@ public class NodeManagerImpl implements 
   }
 
   private Application reservedApplication = null;
+  private Resource reservedResource = null;
 
   @Override
   public synchronized void reserveResource(
@@ -338,7 +339,7 @@ public class NodeManagerImpl implements 
       if (!reservedApplication.applicationId.equals(application.applicationId)) {
         throw new IllegalStateException("Trying to reserve resource " + resource + 
             " for application " + application.getApplicationId() + 
-            " when currently reserved resource " + resource + 
+            " when currently reserved resource " + reservedResource +
             " for application " + reservedApplication.getApplicationId() + 
             " on node " + this);
       }
@@ -350,6 +351,7 @@ public class NodeManagerImpl implements 
       LOG.info("Reserved resource " + resource + " on node " + this + 
           " for application " + application);
     }
+    reservedResource = resource;
   }
 
   @Override
@@ -364,7 +366,8 @@ public class NodeManagerImpl implements 
           " on node " + this);
     }
     
-    this.reservedApplication = null;
+    reservedApplication = null;
+    reservedResource = null;
   }
 
   @Override
@@ -373,6 +376,11 @@ public class NodeManagerImpl implements 
   }
 
   @Override
+  public synchronized Resource getReservedResource() {
+    return reservedResource;
+  }
+
+  @Override
   public String toString() {
     return "host: " + getNodeAddress() + " #containers=" + getNumContainers() +  
       " available=" + getAvailableResource().getMemory() + 

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/QueueMetrics.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/QueueMetrics.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/QueueMetrics.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/QueueMetrics.java Tue May 24 21:15:35 2011
@@ -37,6 +37,8 @@ public class QueueMetrics {
   @Metric("Available memory in GiB") MutableGaugeInt availableGB;
   @Metric("Pending memory allocation in GiB") MutableGaugeInt pendingGB;
   @Metric("# of pending containers") MutableGaugeInt pendingContainers;
+  @Metric("# of reserved memory in GiB") MutableGaugeInt reservedGB;
+  @Metric("# of reserved containers") MutableGaugeInt reservedContainers;
 
   static final Logger LOG = LoggerFactory.getLogger(QueueMetrics.class);
   static final int GB = 1024; // resource.memory is in MB
@@ -47,10 +49,6 @@ public class QueueMetrics {
   static final Splitter Q_SPLITTER =
       Splitter.on('.').omitEmptyStrings().trimResults();
 
-  // MSXXX: until metrics system handle this automatically
-  private static QueueMetrics dummyMetrics = null;
-  private static boolean firstTime = true;
-
   final MetricsRegistry registry;
   final String queueName;
   final QueueMetrics parent;
@@ -83,20 +81,8 @@ public class QueueMetrics {
   public synchronized
   static QueueMetrics forQueue(String queueName, Queue parent,
                                boolean enableUserMetrics) {
-    MetricsSystem ms = null;
-    if (firstTime) {
-      firstTime = false;
-      ms = DefaultMetricsSystem.instance();
-    } else if (!Self.isUnitTest()) {
-      ms = DefaultMetricsSystem.instance();
-    } else {
-      return dummyMetrics; // metrics specific tests should use the long form
-    }
-    QueueMetrics metrics = forQueue(ms, queueName, parent, enableUserMetrics);
-    if (dummyMetrics == null) {
-      dummyMetrics = metrics;
-    }
-    return metrics;
+    return forQueue(DefaultMetricsSystem.instance(), queueName, parent,
+                    enableUserMetrics);
   }
 
   public static QueueMetrics forQueue(MetricsSystem ms, String queueName,
@@ -253,4 +239,28 @@ public class QueueMetrics {
       parent.releaseResources(user, containers, res);
     }
   }
+
+  public void reserveResource(String user, Resource res) {
+    reservedContainers.incr();
+    reservedGB.incr(res.getMemory()/GB);
+    QueueMetrics userMetrics = getUserMetrics(user);
+    if (userMetrics != null) {
+      userMetrics.reserveResource(user, res);
+    }
+    if (parent != null) {
+      parent.reserveResource(user, res);
+    }
+  }
+
+  public void unreserveResource(String user, Resource res) {
+    reservedContainers.decr();
+    reservedGB.decr(res.getMemory()/GB);
+    QueueMetrics userMetrics = getUserMetrics(user);
+    if (userMetrics != null) {
+      userMetrics.unreserveResource(user, res);
+    }
+    if (parent != null) {
+      parent.unreserveResource(user, res);
+    }
+  }
 }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java Tue May 24 21:15:35 2011
@@ -462,8 +462,7 @@ public class LeafQueue implements Queue 
       removeApplication(application, getUser(application.getUser()));
     }
 
-    // Update metrics
-    metrics.finishApp(application);
+    // Clean up metrics etc.
     application.finish();
     
     // Inform the parent queue

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/MockNodes.java Tue May 24 21:15:35 2011
@@ -149,6 +149,11 @@ public class MockNodes {
       }
 
       @Override
+      public Resource getReservedResource() {
+        return null;
+      }
+
+      @Override
       public void reserveResource(Application application, Priority priority,
           Resource resource) {
       }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestQueueMetrics.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestQueueMetrics.java?rev=1127293&r1=1127292&r2=1127293&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestQueueMetrics.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestQueueMetrics.java Tue May 24 21:15:35 2011
@@ -19,12 +19,7 @@ import static org.mockito.Mockito.*;
 public class TestQueueMetrics {
   static final int GB = 1024; // MB
 
-  MetricsSystem ms;
-
-  @Before public void setup() {
-    DefaultMetricsSystem.shutdown(); // not necessary after HADOOP-6919
-    ms = new MetricsSystemImpl();
-  }
+  final MetricsSystem ms = new MetricsSystemImpl();
 
   @Test public void testDefaultSingleQueueMetrics() {
     String queueName = "single";
@@ -42,16 +37,16 @@ public class TestQueueMetrics {
     metrics.incrPendingResources(user, 5, Resources.createResource(15*GB));
     // Available resources is set externally, as it depends on dynamic
     // configurable cluster/queue resources
-    checkResources(queueSource, 0, 0, 100, 15, 5);
+    checkResources(queueSource, 0, 0, 100, 15, 5, 0, 0);
 
     metrics.incrAppsRunning(user);
     checkApps(queueSource, 1, 0, 1, 0, 0, 0);
 
     metrics.allocateResources(user, 3, Resources.createResource(2*GB));
-    checkResources(queueSource, 6, 3, 100, 9, 2);
+    checkResources(queueSource, 6, 3, 100, 9, 2, 0, 0);
 
     metrics.releaseResources(user, 1, Resources.createResource(2*GB));
-    checkResources(queueSource, 4, 2, 100, 9, 2);
+    checkResources(queueSource, 4, 2, 100, 9, 2, 0, 0);
 
     metrics.finishApp(app);
     checkApps(queueSource, 1, 0, 0, 1, 0, 0);
@@ -77,20 +72,20 @@ public class TestQueueMetrics {
     metrics.incrPendingResources(user, 5, Resources.createResource(15*GB));
     // Available resources is set externally, as it depends on dynamic
     // configurable cluster/queue resources
-    checkResources(queueSource, 0, 0, 100, 15, 5);
-    checkResources(userSource, 0, 0, 10, 15, 5);
+    checkResources(queueSource, 0, 0, 100, 15, 5, 0, 0);
+    checkResources(userSource, 0, 0, 10, 15, 5, 0, 0);
 
     metrics.incrAppsRunning(user);
     checkApps(queueSource, 1, 0, 1, 0, 0, 0);
     checkApps(userSource, 1, 0, 1, 0, 0, 0);
 
     metrics.allocateResources(user, 3, Resources.createResource(2*GB));
-    checkResources(queueSource, 6, 3, 100, 9, 2);
-    checkResources(userSource, 6, 3, 10, 9, 2);
+    checkResources(queueSource, 6, 3, 100, 9, 2, 0, 0);
+    checkResources(userSource, 6, 3, 10, 9, 2, 0, 0);
 
     metrics.releaseResources(user, 1, Resources.createResource(2*GB));
-    checkResources(queueSource, 4, 2, 100, 9, 2);
-    checkResources(userSource, 4, 2, 10, 9, 2);
+    checkResources(queueSource, 4, 2, 100, 9, 2, 0, 0);
+    checkResources(userSource, 4, 2, 10, 9, 2, 0, 0);
 
     metrics.finishApp(app);
     checkApps(queueSource, 1, 0, 0, 1, 0, 0);
@@ -126,28 +121,30 @@ public class TestQueueMetrics {
     parentMetrics.setAvailableResourcesToUser(user, Resources.createResource(10*GB));
     metrics.setAvailableResourcesToUser(user, Resources.createResource(10*GB));
     metrics.incrPendingResources(user, 5, Resources.createResource(15*GB));
-    checkResources(queueSource, 0, 0, 100, 15, 5);
-    checkResources(parentQueueSource, 0, 0, 100, 15, 5);
-    checkResources(userSource, 0, 0, 10, 15, 5);
-    checkResources(parentUserSource, 0, 0, 10, 15, 5);
+    checkResources(queueSource, 0, 0, 100, 15, 5, 0, 0);
+    checkResources(parentQueueSource, 0, 0, 100, 15, 5, 0, 0);
+    checkResources(userSource, 0, 0, 10, 15, 5, 0, 0);
+    checkResources(parentUserSource, 0, 0, 10, 15, 5, 0, 0);
 
     metrics.incrAppsRunning(user);
     checkApps(queueSource, 1, 0, 1, 0, 0, 0);
     checkApps(userSource, 1, 0, 1, 0, 0, 0);
 
     metrics.allocateResources(user, 3, Resources.createResource(2*GB));
+    metrics.reserveResource(user, Resources.createResource(3*GB));
     // Available resources is set externally, as it depends on dynamic
     // configurable cluster/queue resources
-    checkResources(queueSource, 6, 3, 100, 9, 2);
-    checkResources(parentQueueSource, 6, 3, 100, 9, 2);
-    checkResources(userSource, 6, 3, 10, 9, 2);
-    checkResources(parentUserSource, 6, 3, 10, 9, 2);
+    checkResources(queueSource, 6, 3, 100, 9, 2, 3, 1);
+    checkResources(parentQueueSource, 6, 3, 100, 9, 2, 3, 1);
+    checkResources(userSource, 6, 3, 10, 9, 2, 3, 1);
+    checkResources(parentUserSource, 6, 3, 10, 9, 2, 3, 1);
 
     metrics.releaseResources(user, 1, Resources.createResource(2*GB));
-    checkResources(queueSource, 4, 2, 100, 9, 2);
-    checkResources(parentQueueSource, 4, 2, 100, 9, 2);
-    checkResources(userSource, 4, 2, 10, 9, 2);
-    checkResources(parentUserSource, 4, 2, 10, 9, 2);
+    metrics.unreserveResource(user, Resources.createResource(3*GB));
+    checkResources(queueSource, 4, 2, 100, 9, 2, 0, 0);
+    checkResources(parentQueueSource, 4, 2, 100, 9, 2, 0, 0);
+    checkResources(userSource, 4, 2, 10, 9, 2, 0, 0);
+    checkResources(parentUserSource, 4, 2, 10, 9, 2, 0, 0);
 
     metrics.finishApp(app);
     checkApps(queueSource, 1, 0, 0, 1, 0, 0);
@@ -168,13 +165,16 @@ public class TestQueueMetrics {
   }
 
   public static void checkResources(MetricsSource source, int allocGB,
-      int allocCtnrs, int availGB, int pendingGB, int pendingCtnrs) {
+      int allocCtnrs, int availGB, int pendingGB, int pendingCtnrs,
+      int reservedGB, int reservedCtnrs) {
     MetricsRecordBuilder rb = getMetrics(source);
     assertGauge("AllocatedGB", allocGB, rb);
     assertGauge("AllocatedContainers", allocCtnrs, rb);
     assertGauge("AvailableGB", availGB, rb);
     assertGauge("PendingGB", pendingGB, rb);
     assertGauge("PendingContainers", pendingCtnrs, rb);
+    assertGauge("ReservedGB", reservedGB, rb);
+    assertGauge("ReservedContainers", reservedCtnrs, rb);
   }
 
   private static Application mockApp(String user) {