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/01/24 00:49:39 UTC

[hbase] branch branch-2.2 updated: HBASE-23710 - Priority configuration for system coprocessors (#1077)

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

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


The following commit(s) were added to refs/heads/branch-2.2 by this push:
     new 4a6d004  HBASE-23710 - Priority configuration for system coprocessors (#1077)
4a6d004 is described below

commit 4a6d0048bcce48259e09dd4915ad803ad352a698
Author: Geoffrey Jacoby <gj...@apache.org>
AuthorDate: Thu Jan 23 16:23:28 2020 -0800

    HBASE-23710 - Priority configuration for system coprocessors (#1077)
    
    Signed-off-by: Viraj Jasani <vj...@apache.org>
---
 .../hadoop/hbase/coprocessor/CoprocessorHost.java     | 19 +++++++++++++++----
 .../hadoop/hbase/coprocessor/TestCoprocessorHost.java | 19 ++++++++++++++++---
 src/main/asciidoc/_chapters/cp.adoc                   | 18 +++++++++++++++++-
 3 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java
index 4243d2f..7e0f2ae 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java
@@ -143,8 +143,16 @@ public abstract class CoprocessorHost<C extends Coprocessor, E extends Coprocess
     if (defaultCPClasses == null || defaultCPClasses.length == 0)
       return;
 
-    int priority = Coprocessor.PRIORITY_SYSTEM;
+    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;
     for (String className : defaultCPClasses) {
+      String[] classNameAndPriority = className.split("\\|");
+      boolean hasPriorityOverride = false;
+      className = classNameAndPriority[0];
+      int overridePriority = Coprocessor.PRIORITY_SYSTEM;
+      if (classNameAndPriority.length > 1){
+        overridePriority = Integer.parseInt(classNameAndPriority[1]);
+        hasPriorityOverride = true;
+      }
       className = className.trim();
       if (findCoprocessor(className) != null) {
         // If already loaded will just continue
@@ -155,13 +163,16 @@ public abstract class CoprocessorHost<C extends Coprocessor, E extends Coprocess
       Thread.currentThread().setContextClassLoader(cl);
       try {
         implClass = cl.loadClass(className);
+        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;
         // Add coprocessors as we go to guard against case where a coprocessor is specified twice
         // in the configuration
-        E env = checkAndLoadInstance(implClass, priority, conf);
+        E env = checkAndLoadInstance(implClass, coprocPriority, conf);
         if (env != null) {
           this.coprocEnvironments.add(env);
-          LOG.info("System coprocessor {} loaded, priority={}.", className, priority);
-          ++priority;
+          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);
+          if (!hasPriorityOverride) {
+            ++currentSystemPriority;
+          }
         }
       } catch (Throwable t) {
         // We always abort if system coprocessors cannot be loaded
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
index 3cf2221..a25c2a6 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorHost.java
@@ -67,29 +67,42 @@ public class TestCoprocessorHost {
 
     CoprocessorHost<RegionCoprocessor, CoprocessorEnvironment<RegionCoprocessor>> host;
     host = new CoprocessorHostForTest<>(conf);
+    int overridePriority = Integer.MAX_VALUE - 1;
+
+    final String coprocessor_v3 =
+      SimpleRegionObserverV3.class.getName() + "|" + overridePriority;
 
     // Try and load a coprocessor three times
     conf.setStrings(key, coprocessor, coprocessor, coprocessor,
-        SimpleRegionObserverV2.class.getName());
+        SimpleRegionObserverV2.class.getName(), coprocessor_v3);
     host.loadSystemCoprocessors(conf, key);
 
-    // Two coprocessors(SimpleRegionObserver and SimpleRegionObserverV2) loaded
-    Assert.assertEquals(2, host.coprocEnvironments.size());
+    // Three coprocessors(SimpleRegionObserver, SimpleRegionObserverV2,
+    // SimpleRegionObserverV3) loaded
+    Assert.assertEquals(3, host.coprocEnvironments.size());
 
     // Check the priority value
     CoprocessorEnvironment<?> simpleEnv = host.findCoprocessorEnvironment(
         SimpleRegionObserver.class.getName());
     CoprocessorEnvironment<?> simpleEnv_v2 = host.findCoprocessorEnvironment(
         SimpleRegionObserverV2.class.getName());
+    CoprocessorEnvironment<?> simpleEnv_v3 = host.findCoprocessorEnvironment(
+      SimpleRegionObserverV3.class.getName());
 
     assertNotNull(simpleEnv);
     assertNotNull(simpleEnv_v2);
+    assertNotNull(simpleEnv_v3);
     assertEquals(Coprocessor.PRIORITY_SYSTEM, simpleEnv.getPriority());
     assertEquals(Coprocessor.PRIORITY_SYSTEM + 1, simpleEnv_v2.getPriority());
+    assertEquals(overridePriority, simpleEnv_v3.getPriority());
   }
 
   public static class SimpleRegionObserverV2 extends SimpleRegionObserver { }
 
+  public static class SimpleRegionObserverV3 extends SimpleRegionObserver {
+
+  }
+
   private static class CoprocessorHostForTest<E extends Coprocessor> extends
       CoprocessorHost<E, CoprocessorEnvironment<E>> {
     final Configuration cpHostConf;
diff --git a/src/main/asciidoc/_chapters/cp.adoc b/src/main/asciidoc/_chapters/cp.adoc
index 5fd80b4..51f71a8 100644
--- a/src/main/asciidoc/_chapters/cp.adoc
+++ b/src/main/asciidoc/_chapters/cp.adoc
@@ -242,12 +242,28 @@ following entry in RegionServer's 'hbase-site.xml' file (generally located under
 If multiple classes are specified for loading, the class names must be comma-separated.
 The framework attempts to load all the configured classes using the default class loader.
 Therefore, the jar file must reside on the server-side HBase classpath.
+
 +
 Coprocessors which are loaded in this way will be active on all regions of all tables.
 These are also called system Coprocessor.
 The first listed Coprocessors will be assigned the priority `Coprocessor.Priority.SYSTEM`.
 Each subsequent coprocessor in the list will have its priority value incremented by one (which
 reduces its priority, because priorities have the natural sort order of Integers).
+
++
+These priority values can be manually overriden in hbase-site.xml. This can be useful if you
+want to guarantee that a coprocessor will execute after another. For example, in the following
+configuration `SumEndPoint` would be guaranteed to go last, except in the case of a tie with
+another coprocessor:
++
+[source,xml]
+----
+<property>
+    <name>hbase.coprocessor.region.classes</name>
+    <value>org.myname.hbase.coprocessor.endpoint.SumEndPoint|2147483647</value>
+</property>
+----
+
 +
 When calling out to registered observers, the framework executes their callbacks methods in the
 sorted order of their priority. +
@@ -791,7 +807,7 @@ Restricting arbitrary user coprocessors can be a big concern in multitenant envi
 
 - `hbase.coprocessor.enabled`: Enables or disables all coprocessors. This will limit the functionality of HBase, as disabling all coprocessors will disable some security providers. An example coproccessor so affected is `org.apache.hadoop.hbase.security.access.AccessController`.
 * `hbase.coprocessor.user.enabled`: Enables or disables loading coprocessors on tables (i.e. user coprocessors).
-* One can statically load coprocessors via the following tunables in `hbase-site.xml`:
+* One can statically load coprocessors, and optionally tune their priorities, via the following tunables in `hbase-site.xml`:
 ** `hbase.coprocessor.regionserver.classes`: A comma-separated list of coprocessors that are loaded by region servers
 ** `hbase.coprocessor.region.classes`: A comma-separated list of RegionObserver and Endpoint coprocessors
 ** `hbase.coprocessor.user.region.classes`: A comma-separated list of coprocessors that are loaded by all regions