You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2008/10/29 22:06:29 UTC

svn commit: r709008 - in /hadoop/hbase/trunk: ./ conf/ src/java/org/apache/hadoop/hbase/ src/java/org/apache/hadoop/hbase/master/ src/java/org/apache/hadoop/hbase/master/metrics/ src/java/org/apache/hadoop/hbase/regionserver/ src/java/org/apache/hadoop...

Author: stack
Date: Wed Oct 29 14:06:29 2008
New Revision: 709008

URL: http://svn.apache.org/viewvc?rev=709008&view=rev
Log:
HBASE-625 Metrics support for cluster load history: emissions and graphs

Added:
    hadoop/hbase/trunk/conf/hadoop-metrics.properties
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java
Modified:
    hadoop/hbase/trunk/CHANGES.txt
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/HServerLoad.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java
    hadoop/hbase/trunk/src/webapps/regionserver/regionserver.jsp

Modified: hadoop/hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/CHANGES.txt (original)
+++ hadoop/hbase/trunk/CHANGES.txt Wed Oct 29 14:06:29 2008
@@ -65,7 +65,6 @@
                (Doğacan Güney via Stack)
    HBASE-908   Add approximate counting to CountingBloomFilter
                (Andrzej Bialecki via Stack)
-   HBASE-576   Investigate IPC performance
    HBASE-920   Make region balancing sloppier
    HBASE-902   Add force compaction and force split operations to UI and Admin
    HBASE-942   Add convenience methods to RowFilterSet
@@ -74,9 +73,6 @@
                SubString operator (Clint Morgan via Stack)
    HBASE-937   Thrift getRow does not support specifying columns
                (Doğacan Güney via Stack)
-   HBASE-940   Make the TableOutputFormat batching-aware
-   HBASE-967   [Optimization] Cache cell maximum length (HCD.getMaxValueLength);
-               its used checking batch size
    HBASE-959   Be able to get multiple RowResult at one time from client side
                (Sishen Freecity via Stack)
    HBASE-936   REST Interface: enable get number of rows from scanner interface
@@ -88,10 +84,15 @@
   NEW FEATURES
    HBASE-875   Use MurmurHash instead of JenkinsHash [in bloomfilters]
                (Andrzej Bialecki via Stack)
+   HBASE-625   Metrics support for cluster load history: emissions and graphs
 
   OPTIMIZATIONS
    HBASE-748   Add an efficient way to batch update many rows
    HBASE-887   Fix a hotspot in scanners
+   HBASE-967   [Optimization] Cache cell maximum length (HCD.getMaxValueLength);
+               its used checking batch size
+   HBASE-940   Make the TableOutputFormat batching-aware
+   HBASE-576   Investigate IPC performance
 
 Release 0.18.0 - September 21st, 2008
 

Added: hadoop/hbase/trunk/conf/hadoop-metrics.properties
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/conf/hadoop-metrics.properties?rev=709008&view=auto
==============================================================================
--- hadoop/hbase/trunk/conf/hadoop-metrics.properties (added)
+++ hadoop/hbase/trunk/conf/hadoop-metrics.properties Wed Oct 29 14:06:29 2008
@@ -0,0 +1,44 @@
+# See http://wiki.apache.org/hadoop/GangliaMetrics
+# And, yes, this file is named hadoop-metrics.properties rather than
+# hbase-metrics.properties because we're leveraging the hadoop metrics
+# package and hadoop-metrics.properties is an hardcoded-name, at least
+# for the moment.
+
+# Configuration of the "hbase" context for null
+hbase.class=org.apache.hadoop.metrics.spi.NullContext
+
+# Configuration of the "hbase" context for file
+# hbase.class=org.apache.hadoop.metrics.file.FileContext
+# hbase.period=10
+# hbase.fileName=/tmp/metrics_hbase.log
+
+# Configuration of the "hbase" context for ganglia
+# hbase.class=org.apache.hadoop.metrics.ganglia.GangliaContext
+# hbase.period=10
+# hbase.servers=GMETADHOST_IP:8649
+
+# Configuration of the "jvm" context for null
+jvm.class=org.apache.hadoop.metrics.spi.NullContext
+
+# Configuration of the "jvm" context for file
+# jvm.class=org.apache.hadoop.metrics.file.FileContext
+# jvm.period=10
+# jvm.fileName=/tmp/metrics_jvm.log
+
+# Configuration of the "jvm" context for ganglia
+# jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext
+# jvm.period=10
+# jvm.servers=GMETADHOST_IP:8649
+
+# Configuration of the "rpc" context for null
+hbase.class=org.apache.hadoop.metrics.spi.NullContext
+
+# Configuration of the "rpc" context for file
+# rpc.class=org.apache.hadoop.metrics.file.FileContext
+# rpc.period=10
+# rpc.fileName=/tmp/metrics_rpc.log
+
+# Configuration of the "rpc" context for ganglia
+# rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext
+# rpc.period=10
+# rpc.servers=GMETADHOST_IP:8649

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/HServerLoad.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/HServerLoad.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/HServerLoad.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/HServerLoad.java Wed Oct 29 14:06:29 2008
@@ -31,6 +31,15 @@
 public class HServerLoad implements WritableComparable {
   private int numberOfRequests;         // number of requests since last report
   private int numberOfRegions;          // number of regions being served
+  /*
+   * Number of storefiles on the regionserver
+   */
+  private int storefiles;
+  
+  /*
+   * Size of the memcaches on this machine in MB.
+   */
+  private int memcacheSizeMB;
   
   /*
    * TODO: Other metrics that might be considered when the master is actually
@@ -44,18 +53,28 @@
    *   <li>server death rate (maybe there is something wrong with this server)</li>
    * </ul>
    */
-  
+
   /** default constructior (used by Writable) */
-  public HServerLoad() {}
+  public HServerLoad() {
+    super();
+  }
   
   /**
    * Constructor
    * @param numberOfRequests
    * @param numberOfRegions
    */
-  public HServerLoad(int numberOfRequests, int numberOfRegions) {
+  public HServerLoad(final int numberOfRequests, final int numberOfRegions,
+      final int storefiles, final int memcacheSizeMB) {
     this.numberOfRequests = numberOfRequests;
     this.numberOfRegions = numberOfRegions;
+    this.storefiles = storefiles;
+    this.memcacheSizeMB = memcacheSizeMB;
+  }
+  
+  public HServerLoad(final HServerLoad hsl) {
+    this(hsl.numberOfRequests, hsl.numberOfRegions, hsl.storefiles,
+      hsl.memcacheSizeMB);
   }
   
   /**
@@ -85,7 +104,8 @@
    * @return The load as a String
    */
   public String toString(int msgInterval) {
-    return "requests: " + numberOfRequests/msgInterval + " regions: " + numberOfRegions;
+    return "requests: " + numberOfRequests/msgInterval +
+      " regions: " + numberOfRegions;
   }
   
   @Override
@@ -116,8 +136,34 @@
     return numberOfRequests;
   }
 
-  // Setters
-  
+  /**
+   * @return Count of storefiles on this regionserver
+   */
+  public int getStorefiles() {
+    return this.storefiles;
+  }
+
+  /**
+   * @return Size of memcaches in kb.
+   */
+  public int getMemcacheSizeInKB() {
+    return this.memcacheSizeMB;
+  }
+
+  /**
+   * @param storefiles Count of storefiles on this server.
+   */
+  public void setStorefiles(int storefiles) {
+    this.storefiles = storefiles;
+  }
+
+  /**
+   * @param memcacheSizeInKB Size of memcache in kb.
+   */
+  public void setMemcacheSizeInKB(int memcacheSizeInKB) {
+    this.memcacheSizeMB = memcacheSizeInKB;
+  }
+
   /**
    * @param numberOfRegions the numberOfRegions to set
    */

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/HMaster.java Wed Oct 29 14:06:29 2008
@@ -63,6 +63,7 @@
 import org.apache.hadoop.hbase.ipc.HMasterRegionInterface;
 import org.apache.hadoop.hbase.ipc.HRegionInterface;
 import org.apache.hadoop.hbase.ipc.HbaseRPC;
+import org.apache.hadoop.hbase.master.metrics.MasterMetrics;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FSUtils;
@@ -147,6 +148,8 @@
   ServerManager serverManager;
   RegionManager regionManager;
   
+  private MasterMetrics metrics;
+  
   /** Build the HMaster out of a raw configuration item.
    * 
    * @param conf - Configuration object
@@ -357,7 +360,6 @@
           startShutdown();
           break;
         }
-        
         // work on the TodoQueue. If that fails, we should shut down.
         if (!processToDoQueue()) {
           break;
@@ -484,6 +486,8 @@
    *  need to install an unexpected exception handler.
    */
   private void startServiceThreads() {
+    // Do after main thread name has been set
+    this.metrics = new MasterMetrics();
     try {
       regionManager.start();
       serverManager.start();
@@ -802,6 +806,13 @@
     return rootServer;
   }
 
+  /**
+   * @return Server metrics
+   */
+  public MasterMetrics getMetrics() {
+    return this.metrics;
+  }
+
   /*
    * Managing leases
    */

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/RegionManager.java Wed Oct 29 14:06:29 2008
@@ -242,11 +242,9 @@
       nregions = 0;
       
       // Advance past any less-loaded servers
-      for (HServerLoad load =
-        new HServerLoad(thisServersLoad.getNumberOfRequests(),
-            thisServersLoad.getNumberOfRegions());
-      load.compareTo(heavierLoad) <= 0 && nregions < nRegionsToAssign;
-      load.setNumberOfRegions(load.getNumberOfRegions() + 1), nregions++) {
+      for (HServerLoad load = new HServerLoad(thisServersLoad);
+        load.compareTo(heavierLoad) <= 0 && nregions < nRegionsToAssign;
+        load.setNumberOfRegions(load.getNumberOfRegions() + 1), nregions++) {
         // continue;
       }
 
@@ -310,9 +308,7 @@
     // unassigned. That is how many regions we should assign to this server.
     int nRegions = 0;
     for (Map.Entry<HServerLoad, Set<String>> e : lightServers.entrySet()) {
-      HServerLoad lightLoad = new HServerLoad(e.getKey().getNumberOfRequests(),
-        e.getKey().getNumberOfRegions());
-
+      HServerLoad lightLoad = new HServerLoad(e.getKey());
       do {
         lightLoad.setNumberOfRegions(lightLoad.getNumberOfRegions() + 1);
         nRegions += 1;

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/ServerManager.java Wed Oct 29 14:06:29 2008
@@ -293,6 +293,7 @@
     serversToServerInfo.put(serverName, serverInfo);
 
     HServerLoad load = serversToLoad.get(serverName);
+    this.master.getMetrics().incrementRequests(load.getNumberOfRequests());
     if (load != null && !load.equals(serverInfo.getLoad())) {
       // We have previous information about the load on this server
       // and the load on this server has changed

Added: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java?rev=709008&view=auto
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java (added)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/master/metrics/MasterMetrics.java Wed Oct 29 14:06:29 2008
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master.metrics;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics.MetricsContext;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.MetricsUtil;
+import org.apache.hadoop.metrics.Updater;
+import org.apache.hadoop.metrics.jvm.JvmMetrics;
+import org.apache.hadoop.metrics.util.MetricsIntValue;
+
+
+/** 
+ * This class is for maintaining the various master statistics
+ * and publishing them through the metrics interfaces.
+ * <p>
+ * This class has a number of metrics variables that are publicly accessible;
+ * these variables (objects) have methods to update their values.
+ */
+public class MasterMetrics implements Updater {
+  private final Log LOG = LogFactory.getLog(this.getClass());
+  private final MetricsRecord metricsRecord;
+  
+  /*
+   * Count of requests to the cluster since last call to metrics update
+   */
+  private final MetricsIntValue cluster_requests =
+    new MetricsIntValue("cluster_requests");
+
+  public MasterMetrics() {
+    MetricsContext context = MetricsUtil.getContext("hbase");
+    metricsRecord = MetricsUtil.createRecord(context, "master");
+    String name = Thread.currentThread().getName();
+    metricsRecord.setTag("Master", name);
+    context.registerUpdater(this);
+    JvmMetrics.init("Master", name);
+    LOG.info("Initialized");
+  }
+  
+  public void shutdown() {
+    // nought to do.
+  }
+    
+  /**
+   * Since this object is a registered updater, this method will be called
+   * periodically, e.g. every 5 seconds.
+   */
+  public void doUpdates(@SuppressWarnings("unused") MetricsContext unused) {
+    synchronized (this) {
+      synchronized(this.cluster_requests) {
+        this.cluster_requests.pushMetric(metricsRecord);
+        // Set requests down to zero again.
+        this.cluster_requests.set(0);
+      }
+    }
+    this.metricsRecord.update();
+  }
+  
+  public void resetAllMinMax() {
+    // Nothing to do
+  }
+
+  /**
+   * @return Count of requests.
+   */
+  public int getRequests() {
+    return this.cluster_requests.get();
+  }
+  
+  /**
+   * @param inc How much to add to requests.
+   */
+  public void incrementRequests(final int inc) {
+    synchronized(this.cluster_requests) {
+      this.cluster_requests.inc(inc);
+    }
+  }
+}
\ No newline at end of file

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Wed Oct 29 14:06:29 2008
@@ -84,6 +84,7 @@
 import org.apache.hadoop.hbase.ipc.HMasterRegionInterface;
 import org.apache.hadoop.hbase.ipc.HRegionInterface;
 import org.apache.hadoop.hbase.ipc.HbaseRPC;
+import org.apache.hadoop.hbase.regionserver.metrics.RegionServerMetrics;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FSUtils;
 import org.apache.hadoop.hbase.util.InfoServer;
@@ -171,6 +172,8 @@
    */
   private final LinkedList<byte[]> reservedSpace = new LinkedList<byte []>();
   
+  private RegionServerMetrics metrics;
+  
   /**
    * Thread to shutdown the region server in an orderly manner.  This thread
    * is registered as a shutdown hook in the HRegionServer constructor and is
@@ -236,7 +239,7 @@
     this.connection = ServerConnectionManager.getConnection(conf);
 
     this.isOnline = false;
-
+    
     // Config'ed params
     this.numRetries =  conf.getInt("hbase.client.retries.number", 2);
     this.threadWakeFrequency = conf.getInt(THREAD_WAKE_FREQUENCY, 10 * 1000);
@@ -296,8 +299,7 @@
   public void run() {
     boolean quiesceRequested = false;
     // A sleeper that sleeps for msgInterval.
-    Sleeper sleeper =
-      new Sleeper(this.msgInterval, this.stopRequested);
+    Sleeper sleeper = new Sleeper(this.msgInterval, this.stopRequested);
     try {
       init(reportForDuty(sleeper));
       long lastMsg = 0;
@@ -317,8 +319,10 @@
             this.outboundMsgs.clear();
           }
           try {
+            doMetrics();
             this.serverInfo.setLoad(new HServerLoad(requestCount.get(),
-                onlineRegions.size()));
+                onlineRegions.size(), this.metrics.storefiles.get(),
+                this.metrics.memcacheSizeMB.get()));
             this.requestCount.set(0);
             HMsg msgs[] = hbaseMaster.regionServerReport(
               serverInfo, outboundArray, getMostLoadedRegions());
@@ -531,6 +535,8 @@
       this.rootDir = new Path(this.conf.get(HConstants.HBASE_DIR));
       this.log = setupHLog();
       this.logFlusher.setHLog(log);
+      // Init in here rather than in constructor after thread name has been set
+      this.metrics = new RegionServerMetrics();
       startServiceThreads();
       isOnline = true;
     } catch (IOException e) {
@@ -543,7 +549,7 @@
       throw ex;
     }
   }
-
+  
   /**
    * Report the status of the server. A server is online once all the startup 
    * is completed (setting up filesystem, starting service threads, etc.). This
@@ -574,6 +580,39 @@
   }
   
   /*
+   * @param interval Interval since last time metrics were called.
+   */
+  protected void doMetrics() {
+    this.metrics.regions.set(this.onlineRegions.size());
+    this.metrics.incrementRequests(this.requestCount.get());
+    // Is this too expensive every three seconds getting a lock on onlineRegions
+    // and then per store carried?  Can I make metrics be sloppier and avoid
+    // the synchronizations?
+    int storefiles = 0;
+    long memcacheSize = 0;
+    synchronized (this.onlineRegions) {
+      for (Map.Entry<Integer, HRegion> e: this.onlineRegions.entrySet()) {
+        HRegion r = e.getValue();
+        memcacheSize += r.memcacheSize.get();
+        synchronized(r.stores) {
+          for(Map.Entry<Integer, HStore> ee: r.stores.entrySet()) {
+            storefiles += ee.getValue().getStorefilesCount();
+          }
+        }
+      }
+    }
+    this.metrics.storefiles.set(storefiles);
+    this.metrics.memcacheSizeMB.set((int)(memcacheSize/(1024*1024)));
+  }
+
+  /**
+   * @return Region server metrics instance.
+   */
+  public RegionServerMetrics getMetrics() {
+    return this.metrics;
+  }
+
+  /*
    * Start maintanence Threads, Server, Worker and lease checker threads.
    * Install an UncaughtExceptionHandler that calls abort of RegionServer if we
    * get an unhandled exception.  We cannot set the handler on all threads.
@@ -748,7 +787,7 @@
     while(!stopRequested.get()) {
       try {
         this.requestCount.set(0);
-        this.serverInfo.setLoad(new HServerLoad(0, onlineRegions.size()));
+        this.serverInfo.setLoad(new HServerLoad(0, onlineRegions.size(), 0, 0));
         lastMsg = System.currentTimeMillis();
         result = this.hbaseMaster.regionServerStartup(serverInfo);
         break;

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java Wed Oct 29 14:06:29 2008
@@ -1960,6 +1960,13 @@
     }
   }
   
+  /**
+   * @return Count of store files
+   */
+  int getStorefilesCount() {
+    return this.storefiles.size();
+  }
+  
   class StoreSize {
     private final long size;
     private final byte[] key;

Added: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java?rev=709008&view=auto
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java (added)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/metrics/RegionServerMetrics.java Wed Oct 29 14:06:29 2008
@@ -0,0 +1,134 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.regionserver.metrics;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.metrics.MetricsContext;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.MetricsUtil;
+import org.apache.hadoop.metrics.Updater;
+import org.apache.hadoop.metrics.jvm.JvmMetrics;
+import org.apache.hadoop.metrics.util.MetricsIntValue;
+
+
+/** 
+ * This class is for maintaining the various regionserver statistics
+ * and publishing them through the metrics interfaces.
+ * <p>
+ * This class has a number of metrics variables that are publicly accessible;
+ * these variables (objects) have methods to update their values.
+ */
+public class RegionServerMetrics implements Updater {
+  private final Log LOG = LogFactory.getLog(this.getClass());
+  private final MetricsRecord metricsRecord;
+  private long lastUpdate = System.currentTimeMillis();
+  
+  /**
+   * Count of regions carried by this regionserver
+   */
+  public final MetricsIntValue regions = new MetricsIntValue("regions");
+  
+  /*
+   * Count of requests to the regionservers since last call to metrics update
+   */
+  private final MetricsIntValue requests = new MetricsIntValue("requests");
+  
+  /**
+   * Count of storefiles open on the regionserver.
+   */
+  public final MetricsIntValue storefiles = new MetricsIntValue("storefiles");
+  
+  /**
+   * Sum of all the memcache sizes in this regionserver in MB
+   */
+  public final MetricsIntValue memcacheSizeMB =
+    new MetricsIntValue("memcachSizeMB");
+
+  public RegionServerMetrics() {
+    MetricsContext context = MetricsUtil.getContext("hbase");
+    metricsRecord = MetricsUtil.createRecord(context, "regionserver");
+    String name = Thread.currentThread().getName();
+    metricsRecord.setTag("RegionServer", name);
+    context.registerUpdater(this);
+    JvmMetrics.init("RegionServer", name);
+    LOG.info("Initialized");
+  }
+  
+  public void shutdown() {
+    // nought to do.
+  }
+    
+  /**
+   * Since this object is a registered updater, this method will be called
+   * periodically, e.g. every 5 seconds.
+   */
+  public void doUpdates(@SuppressWarnings("unused") MetricsContext unused) {
+    synchronized (this) {
+      this.storefiles.pushMetric(this.metricsRecord);
+      this.memcacheSizeMB.pushMetric(this.metricsRecord);
+      this.regions.pushMetric(this.metricsRecord);
+      synchronized(this.requests) {
+        this.requests.pushMetric(this.metricsRecord);
+        // Set requests down to zero again.
+        this.requests.set(0);
+      }
+    }
+    this.metricsRecord.update();
+    this.lastUpdate = System.currentTimeMillis();
+  }
+  
+  public void resetAllMinMax() {
+    // Nothing to do
+  }
+
+  /**
+   * @return Count of requests.
+   */
+  public int getRequests() {
+    return this.requests.get();
+  }
+  
+  /**
+   * @param inc How much to add to requests.
+   */
+  public void incrementRequests(final int inc) {
+    synchronized(this.requests) {
+      this.requests.inc(inc);
+    }
+  }
+  
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("requests=");
+    int seconds = (int)((System.currentTimeMillis() - this.lastUpdate)/1000);
+    if (seconds == 0) {
+      seconds = 1;
+    }
+    sb.append(this.requests.get()/seconds);
+    sb.append(", regions=");
+    sb.append(this.regions.get());
+    sb.append(", storefiles=");
+    sb.append(this.storefiles.get());
+    sb.append(", memcacheSize=");
+    sb.append(this.memcacheSizeMB.get());
+    sb.append("MB");
+    return sb.toString();
+  }
+}

Modified: hadoop/hbase/trunk/src/webapps/regionserver/regionserver.jsp
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/webapps/regionserver/regionserver.jsp?rev=709008&r1=709007&r2=709008&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/webapps/regionserver/regionserver.jsp (original)
+++ hadoop/hbase/trunk/src/webapps/regionserver/regionserver.jsp Wed Oct 29 14:06:29 2008
@@ -3,12 +3,14 @@
   import="org.apache.hadoop.io.Text"
   import="org.apache.hadoop.hbase.regionserver.HRegionServer"
   import="org.apache.hadoop.hbase.regionserver.HRegion"
+  import="org.apache.hadoop.hbase.regionserver.metrics.RegionServerMetrics"
   import="org.apache.hadoop.hbase.util.Bytes"
   import="org.apache.hadoop.hbase.HConstants"
   import="org.apache.hadoop.hbase.HServerInfo"
   import="org.apache.hadoop.hbase.HRegionInfo" %><%
   HRegionServer regionServer = (HRegionServer)getServletContext().getAttribute(HRegionServer.REGIONSERVER);
   HServerInfo serverInfo = regionServer.getServerInfo();
+  RegionServerMetrics metrics = regionServer.getMetrics();
   Collection<HRegionInfo> onlineRegions = regionServer.getSortedOnlineRegionInfos();
   int interval = regionServer.getConfiguration().getInt("hbase.regionserver.msginterval", 3000)/1000;
 %><?xml version="1.0" encoding="UTF-8" ?>
@@ -32,7 +34,7 @@
 <tr><th>Attribute Name</th><th>Value</th><th>Description</th></tr>
 <tr><td>HBase Version</td><td><%= org.apache.hadoop.hbase.util.VersionInfo.getVersion() %>, r<%= org.apache.hadoop.hbase.util.VersionInfo.getRevision() %></td><td>HBase version and svn revision</td></tr>
 <tr><td>HBase Compiled</td><td><%= org.apache.hadoop.hbase.util.VersionInfo.getDate() %>, <%= org.apache.hadoop.hbase.util.VersionInfo.getUser() %></td><td>When HBase version was compiled and by whom</td></tr>
-<tr><td>Load</td><td><%= serverInfo.getLoad().toString(interval) %></td><td>Requests per second and count of loaded regions</td></tr>
+<tr><td>Metrics</td><td><%= metrics.toString() %></td><td>RegionServer Metrics</td></tr>
 </table>
 
 <h2>Online Regions</h2>