HBase协处理器


在很多情况下,做一些简单的相加或者聚合计算的时候,如果直接将计算过程放置在server端,能够减少通讯开销,从而获得很好的性能提升。于是,HBase在0.92之后引入了协处理器(coprocessors),实现一些激动人心的新特性:能够轻易建立二次索引、复杂过滤器(谓词下推)以及访问控制等。


HBase建立了一个框架,它为用户提供类库和运行时环境,使得他们的代码能够在HBase region server和master上处理。


协处理器分两种类型,
系统协处理器 可以全局导入region server上的所有数据表,
表协处理器 即是用户可以指定一张表使用协处理器。


协处理器框架为了更好支持其行为的灵活性,提供了两个不同方面的插件。
一个是 观察者(observer),类似于关系数据库的触发器。
另一个是 终端(endpoint),动态的终端有点像存储过程。




Observer
//--------------------------------
观察者的设计意图是允许用户通过插入代码来重载协处理器框架的upcall方法,而具体的事件触发的callback方法由HBase的核心代码来执行。协处理器框架处理所有的callback调用细节,协处理器自身只需要插入添加或者改变的功能。


以HBase0.92版本为例,它提供了三种观察者接口:
RegionObserver:提供客户端的数据操纵事件钩子:Get、Put、Delete、Scan等。
WALObserver:提供WAL相关操作钩子。
MasterObserver:提供DDL-类型的操作钩子。如创建、删除、修改数据表等。
这些接口可以同时使用在同一个地方,按照不同优先级顺序执行.用户可以任意基于协处理器实现复杂的HBase功能层。HBase有很多种事件可以触发观察者方法,这些事件与方法从HBase0.92版本起,都会集成在HBase API中。不过这些API可能会由于各种原因有所改动,不同版本的接口改动比较大。




EndPoint
//--------------------------------
终端是动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒。客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个终端,它们的实现代码会被目标region远程执行,结果会返回到终端。用户可以结合使用这些强大的插件接口,为HBase添加全新的特性。
终端的使用,如下面流程所示:
定义一个新的protocol接口,必须继承CoprocessorProtocol.
实现终端接口,该实现会被导入region环境执行。
继承抽象类BaseEndpointCoprocessor.
在客户端,终端可以被两个新的HBase Client API调用 。
单个region:
HTableInterface.coprocessorProxy(Class<T> protocol, byte[] row) 。
regions区域:
HTableInterface.coprocessorExec(Class<T> protocol, byte[] startKey, byte[]endKey, Batch.Call<T,R> callable)




有三个方法对Endpoint进行设置:
//--------------------------------
A. 启动全局aggregation,能过操纵所有的表上的数据。通过修改hbase-site.xml这个文件来实现,只需要添加如下代码:

<property> 

<name>hbase.coprocessor.user.region.classes</name> 

<value>org.apache.hadoop.hbase.coprocessor.RowCountEndpoint</value> 

</property>




B. 启用表aggregation,只对特定的表生效。通过HBase Shell 来实现。
(1)disable指定表。hbase> disable 'mytable'
(2)添加aggregation hbase> alter 'mytable', METHOD =>'table_att','coprocessor'=>'|org.apache.hadoop.hbase.coprocessor.RowCountEndpoint ||'
(3)重启指定表 hbase> enable 'mytable'


C. API调用

HTableDescriptor htd = new HTableDescriptor("testTable"); 

htd.setValue("CORPROCESSOR$1",path.toString+"|"+ RowCountEndpoint.class.getCanonicalName()+"|"+Coprocessor.Priority.USER);








总结:


1. 协处理器配置的加载顺序:先加载配置文件中定义的协处理器,后加载表描述符中的协处理器
2. COPROCESSOR$<number>中的number定义了加载的顺序
3. 协处理器配置格式 

›HBase Coprocessor 

–RegionObserver => RDBMS trigger 类似触发器 

–EndpointCoproc => RDBMS stored procedure 终端协处理器(聚合操作..)




[coprocessor jar file location] | class name | [priority] | [arguments]


写法:

alter 'table_name', METHOD => 'table_att', 'coprocessor' => 'path|class|number|args' 

alter 'table_name', METHOD => 'table_att_unset', NAME => 'coprocessor$1'  

(priority 优先级,table_att_unset删除第一个coprocessor)






方案对比:


›HBase Coprocessor 的限制
1-只支持Java – ProtoBuf
2-RegionObserver – 原始数据可修改
3–主要适合做数据聚合
•输出数据少,关系简单,求和什么的
4–直接从 Region Server 中分配资源
5–但是,region split 时可照常使用!最大的优点


›HBase + Hive
1–HQL + Java
2–原始数据得到保留(通过HQL对原始数据进行修改,就不用去写一个复杂的Java程序去修改)
•CREATE TABLE AS select..
3–适合ETL及分析任务
•比如Join
4–可使用YARN进行资源调度,灵活高效
5–Region split 时的问题(若一个region下线了,MR程序也就挂了)





HBase
–需系统层面参数调整:ulimit (./etc/有这个文件去做用户资源调整)
–RegionServer的heap size (HBase与YARN存在内存资源竞争,需要做一个很好的规划)



Hive
–hive.exec.parallel默认是false,需要我们手动去打开
–复合数据类型~ map..需要用hive
–Join优化:hints
– 分区 习惯去做 partition
– 分桶 集中存放,减少文件个数,尤其是做join实,效率提升大 bucket
–用 ORC 、Parquet File 格式提高效率



›Spark SQL
–并不是executors个数越多,性能越好
–脚踏实地的针对具体应用测测性能



 Hive与Spark on YARN存在 资源竞争(共用NM),调节YARN中container个数,来控制资源的使用,定义不同的queue可进行很好的限制