Author: enis
Date: Fri Apr 11 13:46:59 2014
New Revision: 1586653

URL: http://svn.apache.org/r1586653
Log:
HBASE-10785 Metas own location should be cached

Modified:
    
hbase/branches/hbase-10070/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java

Modified: 
hbase/branches/hbase-10070/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/hbase-10070/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java?rev=1586653&r1=1586652&r2=1586653&view=diff
==============================================================================
--- 
hbase/branches/hbase-10070/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
 (original)
+++ 
hbase/branches/hbase-10070/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
 Fri Apr 11 13:46:59 2014
@@ -592,6 +592,8 @@ class ConnectionManager {
     // package protected for the tests
     ClusterStatusListener clusterStatusListener;
 
+    private final Object metaRegionLock = new Object();
+
     private final Object userRegionLock = new Object();
 
     // We have a single lock for master & zk to prevent deadlocks. Having
@@ -1117,7 +1119,7 @@ class ConnectionManager {
       }
 
       if (tableName.equals(TableName.META_TABLE_NAME)) {
-        return this.registry.getMetaRegionLocation();
+        return locateMeta(tableName, useCache, replicaId);
       } else {
         // Region not in the cache - have to go to the meta RS
         return locateRegionInMeta(TableName.META_TABLE_NAME, tableName, row,
@@ -1125,6 +1127,37 @@ class ConnectionManager {
       }
     }
 
+    private RegionLocations locateMeta(final TableName tableName,
+        boolean useCache, int replicaId) throws IOException {
+      // HBASE-10785: We cache the location of the META itself, so that we are 
not overloading
+      // zookeeper with one request for every region lookup. We cache the META 
with empty row
+      // key in MetaCache.
+      byte[] metaCacheKey = HConstants.EMPTY_START_ROW; // use byte[0] as the 
row for meta
+      RegionLocations locations = null;
+      if (useCache) {
+        locations = getCachedLocation(tableName, metaCacheKey);
+        if (locations != null) {
+          return locations;
+        }
+      }
+
+      // only one thread should do the lookup.
+      synchronized (metaRegionLock) {
+        // Check the cache again for a hit in case some other thread made the
+        // same query while we were waiting on the lock.
+        locations = getCachedLocation(tableName, metaCacheKey);
+        if (locations != null) {
+          return locations;
+        }
+        // Look up from zookeeper
+        locations = this.registry.getMetaRegionLocation();
+        if (locations != null) {
+          cacheLocation(tableName, locations);
+        }
+      }
+      return locations;
+    }
+
     /*
      * Search hbase:meta for the HRegionLocation info that contains the table 
and
      * row we're seeking. It will prefetch certain number of regions info and
@@ -1211,7 +1244,7 @@ class ConnectionManager {
         HRegionLocation metaLocation = null;
         try {
           // locate the meta region
-          RegionLocations metaLocations = locateRegion(parentTable, metaKey, 
true, false);
+          RegionLocations metaLocations = locateRegion(parentTable, metaKey, 
tries == 0, false);
           metaLocation = metaLocations == null ? null : 
metaLocations.getDefaultRegionLocation();
           // If null still, go around again.
           if (metaLocation == null) continue;


Reply via email to