Before you can build a processor, it must be developed, compiled, and packaged in a JAR file. The next step is to configure the coprocessor framework to use your coprocessor. You can load the coprocessor from your HBase configuration, so that the coprocessor starts with HBase, or you can configure the coprocessor from the HBase shell, as a table attribute, so that it is loaded dynamically when the table is opened or reopened.
To configure a coprocessor to be loaded when HBase starts, modify the RegionServer's
hbase-site.xml
and configure one of the following properties, based
on the type of observer you are configuring:
hbase.coprocessor.region.classes
for RegionObservers and
Endpoints
hbase.coprocessor.wal.classes
for WALObservers
hbase.coprocessor.master.classes
for MasterObservers
Example 13.1. Example RegionObserver Configuration
In this example, one RegionObserver is configured for all the HBase tables.
<property> <name>hbase.coprocessor.region.classes</name> <value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value> </property>
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 the system coprocessor introduced earlier. 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).
When calling out to registered observers, the framework executes their callbacks methods in the sorted order of their priority. Ties are broken arbitrarily.
You can load a coprocessor on a specific table via a table attribute. The following
example will load the FooRegionObserver
observer when table
t1
is read or re-read.
Example 13.2. Load a Coprocessor On a Table Using HBase Shell
hbase(main):005:0>alter 't1', METHOD => 'table_att', 'coprocessor'=>'hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2'
Updating all regions with the new schema... 1/1 regions updated. Done. 0 row(s) in 1.0730 seconds
hbase(main):006:0>describe 't1'
DESCRIPTION ENABLED {NAME => 't1', coprocessor$1 => 'hdfs:///foo.jar|com.foo.FooRegio false nObserver|1001|arg1=1,arg2=2', FAMILIES => [{NAME => 'c1', DATA_B LOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZ E => '65536', IN_MEMORY => 'false', ENCODE_ON_DISK => 'true', BLO CKCACHE => 'true'}, {NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3' , COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647' , KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCODE_ON_DISK => 'true', BLOCKCACHE => 'true'}]} 1 row(s) in 0.0190 seconds
The coprocessor framework will try to read the class information from the coprocessor
table attribute value. The value contains four pieces of information which are separated by
the |
character.
File path: The jar file containing the coprocessor implementation must be in a location where all region servers can read it. You could copy the file onto the local disk on each region server, but it is recommended to store it in HDFS.
Class name: The full class name of the coprocessor.
Priority: An integer. The framework will determine the execution sequence of all configured observers registered at the same hook using priorities. This field can be left blank. In that case the framework will assign a default priority value.
Arguments: This field is passed to the coprocessor implementation.
Example 13.3. Unload a Coprocessor From a Table Using HBase Shell
hbase(main):007:0>alter 't1', METHOD => 'table_att_unset',
hbase(main):008:0*NAME => 'coprocessor$1'
Updating all regions with the new schema... 1/1 regions updated. Done. 0 row(s) in 1.1130 seconds
hbase(main):009:0>describe 't1'
DESCRIPTION ENABLED {NAME => 't1', FAMILIES => [{NAME => 'c1', DATA_BLOCK_ENCODING => false 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSION S => '3', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '214 7483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN _MEMORY => 'false', ENCODE_ON_DISK => 'true', BLOCKCACHE => 'true '}, {NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_C ELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCO DE_ON_DISK => 'true', BLOCKCACHE => 'true'}]} 1 row(s) in 0.0180 seconds
There is no guarantee that the framework will load a given coprocessor successfully. For example, the shell command neither guarantees a jar file exists at a particular location nor verifies whether the given class is actually contained in the jar file.