HBase协处理器受到Google BigTable协处理器的启发,并在设计上支持高效的并行计算——超越Hadoop MapReduce可以提供的性能。此外,可以将协处理器用于实现新特性,例如二级索引、复杂过滤(下推谓词)和访问控制。
尽管是受BigTable的启发,但HBase协处理器在实现细节上与之存在差别。开发者们实现了一个框架,提供库和运行时环境,用于在HBase域服务器(即相同的Java Virtual Machine(JVM)和主控服务器进程中执行用户代码。相反,Google协处理器不在tablet服务器(等效于HBase域服务器)上运行,而是运行在其地址空间之外(HBase开发者也正考虑在未来的实现中提供一个选项,支持在服务器进程之外部署协处理器代码)。
HBase定义了两种类型的协处理器:
系统协处理器全局加载,适用于域服务器上的所有表和域。
表协处理器在所有域上加载,适用于某个表。
协处理器框架非常灵活,且允许实现两种基本的协处理器类型:
观察者(类似于常规数据库中的触发器)
终端(类似于常规数据库的存储过程)
观察者允许在HBase调用的执行中插入用户代码。此代码由HBase核心代码调用。协处理器框架处理调用用户代码的所有细节。协处理器实现只需要包含所需的功能。HBase 0.92提供了三种观察者接口:
RegionObserver——提供用于数据访问操作的钩子(Get、Put、Delete、Scan等),并支持使用用户代码补充这些操作的方法。RegionObserver协处理器的实例会被加载到每个表域。其作用范围被限定为它所在的域。RegionObserver需要被加载到每个HBase域服务器。
WALObserver——提供用于预写日志(WAL)操作的钩子。这是一种使用自定义用户代码加强WAL写入和重建事件的方法。WALObserver在域服务器上WAL处理的上下文中运行。WALObserver需要被加载到每个HBase域服务器。
MasterObserver——提供用于表管理操作(即创建、删除、修改表等)的钩子,并支持使用用户代码补充这些操作的方法。MasterObserver在HBase主控节点的上下文中运行。
可以将给定类型的观察者链接在一起,从而以指定的优先级顺序执行。某个特定链上的协处理器可以通过在执行过程中传递信息,进而与彼此通信。
终端是一个用于动态远程过程调用(RPC)扩展的接口。终端的实现在服务器端安装,并可以由HBase RPC调用。客户端库提供了便捷的方法用于调用此类动态接口。
构建一个自定义终端的步骤序列如下:
(1) 创建一个继承自CoprocessorProtocol的新接口,支持RPC实现所需要的数据交换。数据转发必须以字节数组的形式实现。
(2) 使用(继承)抽象类BaseEndpointCoprocessor实现终端接口,该抽象类隐藏了一些内部实现细节(例如协处理器框架类的加载)。实现方案必须包含所有必需的协处理器功能,它被加载到域上下文并从中执行。没有什么可以阻止该实现进行HBase操作,而这可能会涉及额外的域服务器。
在客户端,新的HBase客户端API可以调用终端,该API允许在单个域服务器上或者在某个范围内的域服务器上执行它。
当前的实现支持两个用于配置自定义协处理器的选项:
从配置加载(发生在主控服务器或域服务器启动时)
从表属性加载(即当表打开或重新打开时动态加载)
当考虑在自己的开发中使用协处理器时,注意以下几点:
由于在当前的实现中,协处理器在域服务器执行上下文中执行,因此行为不当的协处理器可能会拖垮域服务器。
协处理器执行是非事务性的,这意味着即使某个Put协处理器在Put之外有其他的写操作失败,该Put操作也仍然是有效的。