HBASE-23710 - Priority configuration for system coprocessors (#1077)
Signed-off-by: Viraj Jasani <vjasani@apache.org>
This commit is contained in:
parent
f7eeea0789
commit
a32bd14b27
|
@ -143,8 +143,16 @@ public abstract class CoprocessorHost<C extends Coprocessor, E extends Coprocess
|
||||||
if (defaultCPClasses == null || defaultCPClasses.length == 0)
|
if (defaultCPClasses == null || defaultCPClasses.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int priority = Coprocessor.PRIORITY_SYSTEM;
|
int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;
|
||||||
for (String className : defaultCPClasses) {
|
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();
|
className = className.trim();
|
||||||
if (findCoprocessor(className) != null) {
|
if (findCoprocessor(className) != null) {
|
||||||
// If already loaded will just continue
|
// If already loaded will just continue
|
||||||
|
@ -155,13 +163,16 @@ public abstract class CoprocessorHost<C extends Coprocessor, E extends Coprocess
|
||||||
Thread.currentThread().setContextClassLoader(cl);
|
Thread.currentThread().setContextClassLoader(cl);
|
||||||
try {
|
try {
|
||||||
implClass = cl.loadClass(className);
|
implClass = cl.loadClass(className);
|
||||||
|
int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;
|
||||||
// Add coprocessors as we go to guard against case where a coprocessor is specified twice
|
// Add coprocessors as we go to guard against case where a coprocessor is specified twice
|
||||||
// in the configuration
|
// in the configuration
|
||||||
E env = checkAndLoadInstance(implClass, priority, conf);
|
E env = checkAndLoadInstance(implClass, coprocPriority, conf);
|
||||||
if (env != null) {
|
if (env != null) {
|
||||||
this.coprocEnvironments.add(env);
|
this.coprocEnvironments.add(env);
|
||||||
LOG.info("System coprocessor {} loaded, priority={}.", className, priority);
|
LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);
|
||||||
++priority;
|
if (!hasPriorityOverride) {
|
||||||
|
++currentSystemPriority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// We always abort if system coprocessors cannot be loaded
|
// We always abort if system coprocessors cannot be loaded
|
||||||
|
|
|
@ -67,29 +67,42 @@ public class TestCoprocessorHost {
|
||||||
|
|
||||||
CoprocessorHost<RegionCoprocessor, CoprocessorEnvironment<RegionCoprocessor>> host;
|
CoprocessorHost<RegionCoprocessor, CoprocessorEnvironment<RegionCoprocessor>> host;
|
||||||
host = new CoprocessorHostForTest<>(conf);
|
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
|
// Try and load a coprocessor three times
|
||||||
conf.setStrings(key, coprocessor, coprocessor, coprocessor,
|
conf.setStrings(key, coprocessor, coprocessor, coprocessor,
|
||||||
SimpleRegionObserverV2.class.getName());
|
SimpleRegionObserverV2.class.getName(), coprocessor_v3);
|
||||||
host.loadSystemCoprocessors(conf, key);
|
host.loadSystemCoprocessors(conf, key);
|
||||||
|
|
||||||
// Two coprocessors(SimpleRegionObserver and SimpleRegionObserverV2) loaded
|
// Three coprocessors(SimpleRegionObserver, SimpleRegionObserverV2,
|
||||||
Assert.assertEquals(2, host.coprocEnvironments.size());
|
// SimpleRegionObserverV3) loaded
|
||||||
|
Assert.assertEquals(3, host.coprocEnvironments.size());
|
||||||
|
|
||||||
// Check the priority value
|
// Check the priority value
|
||||||
CoprocessorEnvironment<?> simpleEnv = host.findCoprocessorEnvironment(
|
CoprocessorEnvironment<?> simpleEnv = host.findCoprocessorEnvironment(
|
||||||
SimpleRegionObserver.class.getName());
|
SimpleRegionObserver.class.getName());
|
||||||
CoprocessorEnvironment<?> simpleEnv_v2 = host.findCoprocessorEnvironment(
|
CoprocessorEnvironment<?> simpleEnv_v2 = host.findCoprocessorEnvironment(
|
||||||
SimpleRegionObserverV2.class.getName());
|
SimpleRegionObserverV2.class.getName());
|
||||||
|
CoprocessorEnvironment<?> simpleEnv_v3 = host.findCoprocessorEnvironment(
|
||||||
|
SimpleRegionObserverV3.class.getName());
|
||||||
|
|
||||||
assertNotNull(simpleEnv);
|
assertNotNull(simpleEnv);
|
||||||
assertNotNull(simpleEnv_v2);
|
assertNotNull(simpleEnv_v2);
|
||||||
|
assertNotNull(simpleEnv_v3);
|
||||||
assertEquals(Coprocessor.PRIORITY_SYSTEM, simpleEnv.getPriority());
|
assertEquals(Coprocessor.PRIORITY_SYSTEM, simpleEnv.getPriority());
|
||||||
assertEquals(Coprocessor.PRIORITY_SYSTEM + 1, simpleEnv_v2.getPriority());
|
assertEquals(Coprocessor.PRIORITY_SYSTEM + 1, simpleEnv_v2.getPriority());
|
||||||
|
assertEquals(overridePriority, simpleEnv_v3.getPriority());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SimpleRegionObserverV2 extends SimpleRegionObserver { }
|
public static class SimpleRegionObserverV2 extends SimpleRegionObserver { }
|
||||||
|
|
||||||
|
public static class SimpleRegionObserverV3 extends SimpleRegionObserver {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static class CoprocessorHostForTest<E extends Coprocessor> extends
|
private static class CoprocessorHostForTest<E extends Coprocessor> extends
|
||||||
CoprocessorHost<E, CoprocessorEnvironment<E>> {
|
CoprocessorHost<E, CoprocessorEnvironment<E>> {
|
||||||
final Configuration cpHostConf;
|
final Configuration cpHostConf;
|
||||||
|
|
|
@ -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.
|
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.
|
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.
|
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.
|
Coprocessors which are loaded in this way will be active on all regions of all tables.
|
||||||
These are also called system Coprocessor.
|
These are also called system Coprocessor.
|
||||||
The first listed Coprocessors will be assigned the priority `Coprocessor.Priority.SYSTEM`.
|
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
|
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).
|
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
|
When calling out to registered observers, the framework executes their callbacks methods in the
|
||||||
sorted order of their priority. +
|
sorted order of their priority. +
|
||||||
|
@ -786,7 +802,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.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).
|
* `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.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.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
|
** `hbase.coprocessor.user.region.classes`: A comma-separated list of coprocessors that are loaded by all regions
|
||||||
|
|
Loading…
Reference in New Issue