You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2014/06/28 02:31:21 UTC

[35/49] git commit: HBASE-10785 Metas own location should be cached

HBASE-10785 Metas own location should be cached

git-svn-id: https://svn.apache.org/repos/asf/hbase/branches/hbase-10070@1586653 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/48ffa4d5
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/48ffa4d5
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/48ffa4d5

Branch: refs/heads/master
Commit: 48ffa4d5e615c78f6db8f6c2beddd93460887642
Parents: 579f305
Author: Enis Soztutar <en...@apache.org>
Authored: Fri Apr 11 13:46:59 2014 +0000
Committer: Enis Soztutar <en...@apache.org>
Committed: Fri Jun 27 16:39:39 2014 -0700

----------------------------------------------------------------------
 .../hadoop/hbase/client/ConnectionManager.java  | 36 +++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/48ffa4d5/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
index ff30ef4..d6d6491 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java
@@ -560,6 +560,9 @@ class ConnectionManager {
     // package protected for the tests
     ClusterStatusListener clusterStatusListener;
 
+
+    private final Object metaRegionLock = new Object();
+
     // We have a single lock for master & zk to prevent deadlocks. Having
     //  one lock for ZK and one lock for master is not possible:
     //  When creating a connection to master, we need a connection to ZK to get
@@ -1085,13 +1088,44 @@ 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, row, useCache, retry, replicaId);
       }
     }
 
+    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 the hbase:meta table for the HRegionLocation
       * info that contains the table and row we're seeking.