hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From st...@apache.org
Subject svn commit: r1088703 - in /hbase/trunk: ./ src/main/java/org/apache/hadoop/hbase/regionserver/ src/test/java/org/apache/hadoop/hbase/ src/test/java/org/apache/hadoop/hbase/regionserver/handler/
Date Mon, 04 Apr 2011 18:33:56 GMT
Author: stack
Date: Mon Apr  4 18:33:55 2011
New Revision: 1088703

URL: http://svn.apache.org/viewvc?rev=1088703&view=rev
Log:
HBASE-3694 high multiput latency due to checking global mem store size in a synchronized function

Added:
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerAccounting.java
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestGlobalMemStoreSize.java
Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Mon Apr  4 18:33:55 2011
@@ -127,6 +127,8 @@ Release 0.91.0 - Unreleased
                (Ted Yu via Stack)
    HBASE-3704  Show per region request count in table.jsp
                (Ted Yu via Stack)
+   HBASE-3694  high multiput latency due to checking global mem store size
+               in a synchronized function (Liyin Tang via Stack)
 
   TASK
    HBASE-3559  Move report of split to master OFF the heartbeat channel

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java Mon Apr  4
18:33:55 2011
@@ -424,6 +424,28 @@ public class HRegion implements HeapSize
     }
     return false;
   }
+  
+  public AtomicLong getMemstoreSize() {
+    return memstoreSize;
+  }
+  
+  /**
+   * Increase the size of mem store in this region and the size of global mem 
+   * store
+   * @param memStoreSize
+   * @return the size of memstore in this region
+   */
+  public long addAndGetGlobalMemstoreSize(long memStoreSize) {
+    if (this.rsServices != null) {
+      RegionServerAccounting rsAccounting = 
+        this.rsServices.getRegionServerAccounting();
+      
+      if (rsAccounting != null) {
+        rsAccounting.addAndGetGlobalMemstoreSize(memStoreSize);
+      }
+    }
+    return this.memstoreSize.getAndAdd(memStoreSize);  
+  }
 
   /*
    * Write out an info file under the region directory.  Useful recovering
@@ -1044,7 +1066,7 @@ public class HRegion implements HeapSize
       storeFlushers.clear();
 
       // Set down the memstore size by amount of flush.
-      this.memstoreSize.addAndGet(-currentMemStoreSize);
+      this.addAndGetGlobalMemstoreSize(-currentMemStoreSize);
     } catch (Throwable t) {
       // An exception here means that the snapshot was not persisted.
       // The hlog needs to be replayed so its content is restored to memstore.
@@ -1346,7 +1368,7 @@ public class HRegion implements HeapSize
 
       // Now make changes to the memstore.
       long addedSize = applyFamilyMapToMemstore(familyMap);
-      flush = isFlushSize(memstoreSize.addAndGet(addedSize));
+      flush = isFlushSize(this.addAndGetGlobalMemstoreSize(addedSize));
 
       if (coprocessorHost != null) {
         coprocessorHost.postDelete(familyMap, writeToWAL);
@@ -1478,7 +1500,7 @@ public class HRegion implements HeapSize
       this.writeRequestsCount.increment();
       try {
         long addedSize = doMiniBatchPut(batchOp);
-        newSize = memstoreSize.addAndGet(addedSize);
+        newSize = this.addAndGetGlobalMemstoreSize(addedSize);
       } finally {
         closeRegionOperation();
       }
@@ -1858,7 +1880,7 @@ public class HRegion implements HeapSize
       }
 
       long addedSize = applyFamilyMapToMemstore(familyMap);
-      flush = isFlushSize(memstoreSize.addAndGet(addedSize));
+      flush = isFlushSize(this.addAndGetGlobalMemstoreSize(addedSize));
     } finally {
       this.updatesLock.readLock().unlock();
     }
@@ -2172,7 +2194,7 @@ public class HRegion implements HeapSize
    * @return True if we should flush.
    */
   protected boolean restoreEdit(final Store s, final KeyValue kv) {
-    return isFlushSize(this.memstoreSize.addAndGet(s.add(kv)));
+    return isFlushSize(this.addAndGetGlobalMemstoreSize(s.add(kv)));
   }
 
   /*
@@ -3281,7 +3303,7 @@ public class HRegion implements HeapSize
             walEdits, now);
         }
 
-        size = this.memstoreSize.addAndGet(size);
+        size = this.addAndGetGlobalMemstoreSize(size);
         flush = isFlushSize(size);
       } finally {
         this.updatesLock.readLock().unlock();
@@ -3357,7 +3379,7 @@ public class HRegion implements HeapSize
         // returns the change in the size of the memstore from operation
         long size = store.updateColumnValue(row, family, qualifier, result);
 
-        size = this.memstoreSize.addAndGet(size);
+        size = this.addAndGetGlobalMemstoreSize(size);
         flush = isFlushSize(size);
       } finally {
         this.updatesLock.readLock().unlock();

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Mon
Apr  4 18:33:55 2011
@@ -273,6 +273,8 @@ public class HRegionServer implements HR
   // Replication services. If no replication, this handler will be null.
   private Replication replicationHandler;
 
+  private final RegionServerAccounting regionServerAccounting;
+  
   /**
    * Starts a HRegionServer at the default location
    *
@@ -351,6 +353,8 @@ public class HRegionServer implements HR
     // login the server principal (if using secure Hadoop)
     User.login(conf, "hbase.regionserver.keytab.file",
         "hbase.regionserver.kerberos.principal", serverInfo.getHostname());
+    
+    regionServerAccounting = new RegionServerAccounting();
   }
 
   private static final int NORMAL_QOS = 0;
@@ -883,6 +887,10 @@ public class HRegionServer implements HR
     }
   }
 
+  public RegionServerAccounting getRegionServerAccounting() {
+    return regionServerAccounting;
+  }
+  
   /*
    * @param r Region to get RegionLoad for.
    *
@@ -2524,19 +2532,6 @@ public class HRegionServer implements HR
   }
 
   /**
-   * Return the total size of all memstores in every region.
-   *
-   * @return memstore size in bytes
-   */
-  public long getGlobalMemStoreSize() {
-    long total = 0;
-    for (HRegion region : onlineRegions.values()) {
-      total += region.memstoreSize.get();
-    }
-    return total;
-  }
-
-  /**
    * @return Return the leases.
    */
   protected Leases getLeases() {

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java Mon
Apr  4 18:33:55 2011
@@ -290,14 +290,16 @@ class MemStoreFlusher extends Thread imp
    * Return true if global memory usage is above the high watermark
    */
   private boolean isAboveHighWaterMark() {
-    return server.getGlobalMemStoreSize() >= globalMemStoreLimit;
+    return server.getRegionServerAccounting().
+      getGlobalMemstoreSize() >= globalMemStoreLimit;
   }
 
   /**
    * Return true if we're above the high watermark
    */
   private boolean isAboveLowWaterMark() {
-    return server.getGlobalMemStoreSize() >= globalMemStoreLimitLowMark;
+    return server.getRegionServerAccounting().
+      getGlobalMemstoreSize() >= globalMemStoreLimitLowMark;
   }
 
   public void requestFlush(HRegion r) {

Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerAccounting.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerAccounting.java?rev=1088703&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerAccounting.java
(added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerAccounting.java
Mon Apr  4 18:33:55 2011
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * RegionServerAccounting keeps record of some basic real time information about
+ * the Region Server. Currently, it only keeps record the global memstore size. 
+ */
+public class RegionServerAccounting {
+
+  private final AtomicLong atomicGlobalMemstoreSize = new AtomicLong(0);
+  
+  /**
+   * @return the global Memstore size in the RegionServer
+   */
+  public long getGlobalMemstoreSize() {
+    return atomicGlobalMemstoreSize.get();
+  }
+  
+  /**
+   * @param memStoreSize the Memstore size will be added to 
+   *        the global Memstore size 
+   * @return the global Memstore size in the RegionServer 
+   */
+  public long addAndGetGlobalMemstoreSize(long memStoreSize) {
+    return atomicGlobalMemstoreSize.addAndGet(memStoreSize);
+  }
+ 
+}

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java
Mon Apr  4 18:33:55 2011
@@ -65,6 +65,11 @@ public interface RegionServerServices ex
    * @return The HServerInfo for this RegionServer.
    */
   public HServerInfo getServerInfo();
+  
+  /**
+   * @return the RegionServerAccounting for this Region Server
+   */
+  public RegionServerAccounting getRegionServerAccounting();
 
   /**
    * Tasks to perform after region open to complete deploy of region on

Added: hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestGlobalMemStoreSize.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestGlobalMemStoreSize.java?rev=1088703&view=auto
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestGlobalMemStoreSize.java (added)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/TestGlobalMemStoreSize.java Mon Apr
 4 18:33:55 2011
@@ -0,0 +1,134 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional infomation
+ * 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;
+
+import static org.junit.Assert.*;
+import java.util.List;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.JVMClusterUtil;
+import org.junit.Test;
+
+/**
+ * Test HBASE-3694 whether the GlobalMemStoreSize is the same as the summary
+ * of all the online region's MemStoreSize
+ */
+public class TestGlobalMemStoreSize {
+  private final Log LOG = LogFactory.getLog(this.getClass().getName());
+  private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+  
+  private static int regionServerNum =4;
+  private static int regionNum = 16;
+  // total region num = region num + root and meta regions
+  private static int totalRegionNum = regionNum+2;
+
+  private HBaseTestingUtility TEST_UTIL;
+  private MiniHBaseCluster cluster;
+  
+  /**
+   * Test the global mem store size in the region server is equal to sum of each
+   * region's mem store size
+   * @throws Exception 
+   */
+  @Test
+  public void testGlobalMemStore() throws Exception {
+    // Start the cluster
+    LOG.info("Starting cluster");
+    Configuration conf = HBaseConfiguration.create();
+    conf.setInt("hbase.master.assignment.timeoutmonitor.period", 2000);
+    conf.setInt("hbase.master.assignment.timeoutmonitor.timeout", 5000);
+    TEST_UTIL = new HBaseTestingUtility(conf);
+    TEST_UTIL.startMiniCluster(1, regionServerNum);
+    cluster = TEST_UTIL.getHBaseCluster();
+    LOG.info("Waiting for active/ready master");
+    cluster.waitForActiveAndReadyMaster();
+    
+    // Create a table with regions
+    byte [] table = Bytes.toBytes("TestGlobalMemStoreSize");
+    byte [] family = Bytes.toBytes("family");
+    LOG.info("Creating table with " + regionNum + " regions");
+    HTable ht = TEST_UTIL.createTable(table, family);
+    int numRegions = TEST_UTIL.createMultiRegions(conf, ht, family,
+        regionNum);
+    assertEquals(regionNum,numRegions);
+    waitForAllRegionsAssigned();
+    
+    for (HRegionServer server : getOnlineRegionServers()) {
+      long globalMemStoreSize = 0;
+      for(HRegionInfo regionInfo : server.getOnlineRegions()) {
+        globalMemStoreSize += 
+          server.getFromOnlineRegions(regionInfo.getEncodedName()).
+          getMemstoreSize().get();
+      }
+      assertEquals(server.getRegionServerAccounting().getGlobalMemstoreSize(),
+          globalMemStoreSize);
+    }
+    
+    // check the global memstore size after flush
+    for (HRegionServer server : getOnlineRegionServers()) {
+      for(HRegionInfo regionInfo : server.getOnlineRegions()) {
+        HRegion region= 
+          server.getFromOnlineRegions(regionInfo.getEncodedName());
+        region.flushcache();
+      }
+      assertEquals(server.getRegionServerAccounting().getGlobalMemstoreSize(),
+          0);
+    }
+  }
+  
+  /** figure out how many regions are currently being served. */
+  private int getRegionCount() {
+    int total = 0;
+    for (HRegionServer server : getOnlineRegionServers()) {
+      total += server.getOnlineRegions().size();
+    }
+    return total;
+  }
+  
+  private List<HRegionServer> getOnlineRegionServers() {
+    List<HRegionServer> list = new ArrayList<HRegionServer>();
+    for (JVMClusterUtil.RegionServerThread rst : 
+          cluster.getRegionServerThreads()) {
+      if (rst.getRegionServer().isOnline()) {
+        list.add(rst.getRegionServer());
+      }
+    }
+    return list;
+  }
+
+  /**
+   * Wait until all the regions are assigned.
+   */
+  private void waitForAllRegionsAssigned() {
+    while (getRegionCount() < totalRegionNum) {
+      LOG.debug("Waiting for there to be "+totalRegionNum+" regions, but there are " + getRegionCount()
+ " right now.");
+      try {
+        Thread.sleep(1000);
+      } catch (InterruptedException e) {}
+    }
+  }
+}
+

Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java?rev=1088703&r1=1088702&r2=1088703&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java
(original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java
Mon Apr  4 18:33:55 2011
@@ -38,6 +38,7 @@ import org.apache.hadoop.hbase.ipc.HBase
 import org.apache.hadoop.hbase.regionserver.CompactionRequestor;
 import org.apache.hadoop.hbase.regionserver.FlushRequester;
 import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.RegionServerAccounting;
 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
 import org.apache.hadoop.hbase.regionserver.wal.HLog;
 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
@@ -181,6 +182,10 @@ public class TestOpenRegionHandler {
     public ZooKeeperWatcher getZooKeeperWatcher() {
       return null;
     }
+    
+    public RegionServerAccounting getRegionServerAccounting() {
+      return null;
+    }
   };
 
   /**



Mime
View raw message