要使协处理器可用于 HBase,必须静态(通过 HBase 配置)或动态(使用 HBase Shell 或 Java API)加载。
请按照以下步骤静态加载协处理器。请记住,必须重新启动 HBase 才能卸载已静态加载的协处理器。
在 hbase-site.xml 中定义协处理器,<property>元素包含<name>和<value>子元素。 <name>应为以下之一:</name></value></name></property>
RegionObservers 和 Endpoints 的hbase.coprocessor.region.classes
。
WALObservers 的hbase.coprocessor.wal.classes
。
MasterObservers 的hbase.coprocessor.master.classes
。
<value>必须包含协处理器实现类的完全限定类名。</value>
例如,要加载协处理器(在类 SumEndPoint.java 中实现),您必须在 RegionServer 的'hbase-site.xml'文件中创建以下条目(通常位于'conf'目录下):
<property>
<name>hbase.coprocessor.region.classes</name>
<value>org.myname.hbase.coprocessor.endpoint.SumEndPoint</value>
</property>
如果为加载指定了多个类,则类名必须以逗号分隔。框架尝试使用默认的类加载器加载所有已配置的类。因此,jar 文件必须驻留在服务器端 HBase 类路径中。
以这种方式加载的协处理器将在所有表的所有区域上处于活动状态。这些也称为系统协处理器。将为第一个列出的协处理器分配优先级Coprocessor.Priority.SYSTEM
。列表中的每个后续协处理器的优先级值都会增加 1(这会降低其优先级,因为优先级具有整数的自然排序顺序)。
当调用注册的观察者时,框架以其优先级的排序顺序执行其回调方法。关系是任意破坏的。
将您的代码放在 HBase 的类路径上。一种简单的方法是将 jar(包含代码和所有依赖项)放入 HBase 安装的lib/
目录中。
重启 HBase。
从hbase-site.xml
中删除协处理器的<property>元素,包括子元素。</property>
Restart HBase.
(可选)从类路径或 HBase 的lib/
目录中删除协处理器的 JAR 文件。
您也可以动态加载协处理器,而无需重新启动 HBase。这似乎比静态加载更好,但动态加载的协处理器是基于每个表加载的,并且只能用于加载它们的表。因此,动态加载的表有时称为表协处理器。
此外,动态加载协处理器充当表上的模式更改,并且必须使表脱机以加载协处理器。
有三种方法可以动态加载协处理器。
假设
以下提到的说明做出以下假设:
名为
coprocessor.jar
的 JAR 包含协处理器实现及其所有依赖项。JAR 在
hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar
等某些位置可用于 HDFS。
使用 HBase Shell 禁用表:
hbase> disable 'users'
使用如下命令加载协处理器:
hbase alter 'users', METHOD => 'table_att', 'Coprocessor'=>'hdfs://<namenode>:<port>/
user/<hadoop-user>/coprocessor.jar| org.myname.hbase.Coprocessor.RegionObserverExample|1073741823|
arg1=1,arg2=2'
协处理器框架将尝试从协处理器表属性值中读取类信息。该值包含由管道(|
)字符分隔的四条信息。
文件路径:包含协处理器实现的 jar 文件必须位于所有区域服务器都可以读取它的位置。您可以将文件复制到每个区域服务器上的本地磁盘上,但建议将其存储在 HDFS 中。 HBASE-14548 允许指定包含 jar 或某些通配符的目录,例如:hdfs:// <namenode>: <port>/ user / <hadoop-user>/或 hdfs:// <namenode>: <port>/ user / <hadoop-user>/*.jar。请注意,如果指定了目录,则会添加目录中的所有 jar 文件(.jar)。它不搜索子目录中的文件。如果要指定目录,请不要使用通配符。此增强功能也适用于通过 JAVA API 的用法。</hadoop-user></port></namenode></hadoop-user></port></namenode>
类名:协处理器的完整类名。
优先级:整数。该框架将使用优先级确定在同一个钩子上注册的所有已配置观察者的执行顺序。此字段可以留空。在这种情况下,框架将分配默认优先级值。
参数(可选):此字段传递给协处理器实现。这是可选的。
启用表格。
hbase(main):003:0> enable 'users'
验证协处理器已加载:
hbase(main):04:0> describe 'users'
协处理器应列在TABLE_ATTRIBUTES
中。
以下 Java 代码显示如何使用HTableDescriptor
的setValue()
方法在users
表上加载协处理器。
TableName tableName = TableName.valueOf("users");
String path = "hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar";
Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin();
admin.disableTable(tableName);
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
columnFamily1.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily1);
HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
columnFamily2.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily2);
hTableDescriptor.setValue("COPROCESSOR$1", path + "|"
+ RegionObserverExample.class.getCanonicalName() + "|"
+ Coprocessor.PRIORITY_USER);
admin.modifyTable(tableName, hTableDescriptor);
admin.enableTable(tableName);
在 HBase 0.96 及更新版本中,HTableDescriptor
的addCoprocessor()
方法提供了一种动态加载协处理器的简便方法。
TableName tableName = TableName.valueOf("users");
Path path = new Path("hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar");
Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin();
admin.disableTable(tableName);
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
columnFamily1.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily1);
HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
columnFamily2.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily2);
hTableDescriptor.addCoprocessor(RegionObserverExample.class.getCanonicalName(), path,
Coprocessor.PRIORITY_USER, null);
admin.modifyTable(tableName, hTableDescriptor);
admin.enableTable(tableName);
无法保证框架将成功加载给定的协处理器。例如,shell 命令既不保证特定位置存在 jar 文件,也不验证给定类是否实际包含在 jar 文件中。
禁用该表。
hbase> disable 'users'
更改表以删除协处理器。
hbase> alter 'users', METHOD => 'table_att_unset', NAME => 'coprocessor$1'
Enable the table.
hbase> enable 'users'
通过使用setValue()
或addCoprocessor()
方法重新加载表定义而不设置协处理器的值。这将删除附加到表的任何协处理器。
TableName tableName = TableName.valueOf("users");
String path = "hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar";
Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin();
admin.disableTable(tableName);
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
columnFamily1.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily1);
HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
columnFamily2.setMaxVersions(3);
hTableDescriptor.addFamily(columnFamily2);
admin.modifyTable(tableName, hTableDescriptor);
admin.enableTable(tableName);
在 HBase 0.96 及更高版本中,您可以改为使用HTableDescriptor
类的removeCoprocessor()
方法。