You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by vj...@apache.org on 2020/05/06 09:48:40 UTC

[hbase] branch branch-2.3 updated: HBASE-24211: Create table is slow in large cluster when AccessController is enabled. (#1631)

This is an automated email from the ASF dual-hosted git repository.

vjasani pushed a commit to branch branch-2.3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.3 by this push:
     new 20c2f28  HBASE-24211: Create table is slow in large cluster when AccessController is enabled. (#1631)
20c2f28 is described below

commit 20c2f2898c91dfba2a7ee3bbe6da6d3f3f031857
Author: Mohammad Arshad <ar...@apache.org>
AuthorDate: Wed May 6 15:12:20 2020 +0530

    HBASE-24211: Create table is slow in large cluster when AccessController is enabled. (#1631)
    
    Signed-off-by: Viraj Jasani <vj...@apache.org>
---
 .../hbase/security/access/ZKPermissionWatcher.java | 35 ++++++------
 .../org/apache/hadoop/hbase/zookeeper/ZKUtil.java  | 63 +++++++++++++++++++---
 2 files changed, 74 insertions(+), 24 deletions(-)

diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.java
index b410719..db0e535 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.java
@@ -185,25 +185,28 @@ public class ZKPermissionWatcher extends ZKListener implements Closeable {
   public void nodeChildrenChanged(final String path) {
     waitUntilStarted();
     if (path.equals(aclZNode)) {
-      try {
-        final List<ZKUtil.NodeAndData> nodeList =
-            ZKUtil.getChildDataAndWatchForNewChildren(watcher, aclZNode);
-        // preempt any existing nodeChildrenChanged event processing
-        if (childrenChangedFuture != null && !childrenChangedFuture.isDone()) {
-          boolean cancelled = childrenChangedFuture.cancel(true);
-          if (!cancelled) {
-            // task may have finished between our check and attempted cancel, this is fine.
-            if (! childrenChangedFuture.isDone()) {
-              LOG.warn("Could not cancel processing node children changed event, " +
-                  "please file a JIRA and attach logs if possible.");
-            }
+      // preempt any existing nodeChildrenChanged event processing
+      if (childrenChangedFuture != null && !childrenChangedFuture.isDone()) {
+        boolean cancelled = childrenChangedFuture.cancel(true);
+        if (!cancelled) {
+          // task may have finished between our check and attempted cancel, this is fine.
+          if (!childrenChangedFuture.isDone()) {
+            LOG.warn("Could not cancel processing node children changed event, "
+              + "please file a JIRA and attach logs if possible.");
           }
         }
-        childrenChangedFuture = asyncProcessNodeUpdate(() -> refreshNodes(nodeList));
-      } catch (KeeperException ke) {
-        LOG.error("Error reading data from zookeeper for path "+path, ke);
-        watcher.abort("ZooKeeper error get node children for path "+path, ke);
       }
+      childrenChangedFuture = asyncProcessNodeUpdate(() -> {
+        try {
+          final List<ZKUtil.NodeAndData> nodeList =
+            ZKUtil.getChildDataAndWatchForNewChildren(watcher, aclZNode, false);
+          refreshNodes(nodeList);
+        } catch (KeeperException ke) {
+          String msg = "ZooKeeper error while reading node children data for path " + path;
+          LOG.error(msg, ke);
+          watcher.abort(msg, ke);
+        }
+      });
     }
   }
 
diff --git a/hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java b/hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
index 3f0f93f..19d11d0 100644
--- a/hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
+++ b/hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java
@@ -634,9 +634,24 @@ public final class ZKUtil {
    * @return data of the specified znode, or null
    * @throws KeeperException if unexpected zookeeper exception
    */
-  public static byte [] getDataAndWatch(ZKWatcher zkw, String znode)
+  public static byte[] getDataAndWatch(ZKWatcher zkw, String znode) throws KeeperException {
+    return getDataInternal(zkw, znode, null, true, true);
+  }
+
+  /**
+   * Get the data at the specified znode and set a watch.
+   * Returns the data and sets a watch if the node exists.  Returns null and no
+   * watch is set if the node does not exist or there is an exception.
+   *
+   * @param zkw              zk reference
+   * @param znode            path of node
+   * @param throwOnInterrupt if false then just interrupt the thread, do not throw exception
+   * @return data of the specified znode, or null
+   * @throws KeeperException if unexpected zookeeper exception
+   */
+  public static byte[] getDataAndWatch(ZKWatcher zkw, String znode, boolean throwOnInterrupt)
     throws KeeperException {
-    return getDataInternal(zkw, znode, null, true);
+    return getDataInternal(zkw, znode, null, true, throwOnInterrupt);
   }
 
   /**
@@ -653,11 +668,11 @@ public final class ZKUtil {
    */
   public static byte[] getDataAndWatch(ZKWatcher zkw, String znode,
                                        Stat stat) throws KeeperException {
-    return getDataInternal(zkw, znode, stat, true);
+    return getDataInternal(zkw, znode, stat, true, true);
   }
 
-  private static byte[] getDataInternal(ZKWatcher zkw, String znode, Stat stat,
-                                        boolean watcherSet)
+  private static byte[] getDataInternal(ZKWatcher zkw, String znode, Stat stat, boolean watcherSet,
+    boolean throwOnInterrupt)
       throws KeeperException {
     try {
       byte [] data = zkw.getRecoverableZooKeeper().getData(znode, zkw, stat);
@@ -675,7 +690,11 @@ public final class ZKUtil {
       return null;
     } catch (InterruptedException e) {
       LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
-      zkw.interruptedException(e);
+      if (throwOnInterrupt) {
+        zkw.interruptedException(e);
+      } else {
+        zkw.interruptedExceptionNoThrow(e, true);
+      }
       return null;
     }
   }
@@ -735,15 +754,43 @@ public final class ZKUtil {
    * @deprecated Unused
    */
   @Deprecated
+  public static List<NodeAndData> getChildDataAndWatchForNewChildren(ZKWatcher zkw, String baseNode)
+    throws KeeperException {
+    return getChildDataAndWatchForNewChildren(zkw, baseNode, true);
+  }
+
+  /**
+   * Returns the date of child znodes of the specified znode.  Also sets a watch on
+   * the specified znode which will capture a NodeDeleted event on the specified
+   * znode as well as NodeChildrenChanged if any children of the specified znode
+   * are created or deleted.
+   *
+   * Returns null if the specified node does not exist.  Otherwise returns a
+   * list of children of the specified node.  If the node exists but it has no
+   * children, an empty list will be returned.
+   *
+   * @param zkw zk reference
+   * @param baseNode path of node to list and watch children of
+   * @param throwOnInterrupt if true then just interrupt the thread, do not throw exception
+   * @return list of data of children of the specified node, an empty list if the node
+   *          exists but has no children, and null if the node does not exist
+   * @throws KeeperException if unexpected zookeeper exception
+   * @deprecated Unused
+   */
+  @Deprecated
   public static List<NodeAndData> getChildDataAndWatchForNewChildren(
-          ZKWatcher zkw, String baseNode) throws KeeperException {
+          ZKWatcher zkw, String baseNode, boolean throwOnInterrupt) throws KeeperException {
     List<String> nodes =
       ZKUtil.listChildrenAndWatchForNewChildren(zkw, baseNode);
     if (nodes != null) {
       List<NodeAndData> newNodes = new ArrayList<>();
       for (String node : nodes) {
+        if (Thread.interrupted()) {
+          // Partial data should not be processed. Cancel processing by sending empty list.
+          return Collections.emptyList();
+        }
         String nodePath = ZNodePaths.joinZNode(baseNode, node);
-        byte[] data = ZKUtil.getDataAndWatch(zkw, nodePath);
+        byte[] data = ZKUtil.getDataAndWatch(zkw, nodePath, throwOnInterrupt);
         newNodes.add(new NodeAndData(nodePath, data));
       }
       return newNodes;