hbase0.94协处理器实例

来源:互联网 发布:浙江软件学院 编辑:程序博客网 时间:2024/05/22 08:28

最近遇到一个业务需求,是将hbase中的一张表的全量数据按照指定json格式写出成文本文件,提供给其他人做分析。考虑了一下决定使用hbase自身的协处理器特性来实现,下面详细记录一下过程。

协处理器介绍

自HBase 0.92版本起,开始支处持协理器特性,大大地增强了HBase在某些特定场景下的可用性。从名字上即可知道“协处理器”意指协助处理,它主要分成以下两种。

1)观察者(Observer)

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

以HBase0.92版本为例,它提供了三种观察者接口:

  • RegionObserver:提供客户端的数据操纵事件钩子:Get、Put、Delete、Scan等。
  • WALObserver:提供WAL相关操作钩子。
  • MasterObserver:提供DDL-类型的操作钩子。如创建、删除、修改数据表等。

2)终端(Endpoint)

终端是动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒。客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个终端,它们的实现代码会被目标region远程执行,结果会返回到终端。用户可以结合使用这些强大的插件接口,为HBase添加全新的特性。终端的使用,如下面流程所示:

  1. 定义一个新的protocol接口,必须继承CoprocessorProtocol.
  2. 实现终端接口,该实现会被导入region环境执行。
  3. 继承抽象类BaseEndpointCoprocessor.
  4. 在客户端,终端可以被两个新的HBase Client API调用 。单个region:HTableInterface.coprocessorProxy(Class<T> protocol, byte[] row) 。rigons区域:HTableInterface.coprocessorExec(Class<T> protocol, byte[] startKey, byte[] endKey, Batch.Call<T,R> callable)

协处理器实践

本次实践主要是针对开头说的hbase表数据写出文件这一业务需求,自定义Endpoint类型的协处理器。具体步骤如下:

1)自定义EndPoint类型协处理器主要分服务端和客户端两块,先介绍服务端代码

1.1. 自定义写文件协议接口,继承CoprocessorProtocol
<pre name="code" class="java">/** * 自定义写文件协议 * @author lchen */public interface WriteFileProtocol extends CoprocessorProtocol{/** * 写文件方法 * @param outFilePath 写出文件路径 * @return操作成功,返回true; 默认false *自定义协议中的每个方法都必须有返回值,具体参阅源码注释 * @throws IOException */public boolean writeFile(String outFilePath) throws IOException;}
</pre><pre>
1.2 自定义写文件协处理器类,继承BaseEndpointCoprocessor,实现写文件协议WriteFileProtocol
<pre name="code" class="java">/** * 自定义写文件协处理器 * 需要继承BaseEndpointCoprocessor类,以及实现自定义写文件协议 * @author lchen */public class WriteFileCoprocessor extends BaseEndpointCoprocessor implements WriteFileProtocol{private static final Logger logger = Logger.getLogger(WriteFileCoprocessor.class);// 输出文件private File outFile = null;private String currentHRegionName = null;@Overridepublic boolean writeFile(String outFilePath) throws IOException {boolean flag = false;// 构建scanScan scan = new Scan();scan.setCacheBlocks(false);scan.setMaxVersions();// 获取当前环境中的region块HRegion hRegion = ((RegionCoprocessorEnvironment) getEnvironment()).getRegion();currentHRegionName = String.valueOf(hRegion.getRegionId());logger.info("当前处理的region块编号: "+currentHRegionName);// path+fileName region块名称作为输出文件名outFile = new File(outFilePath+currentHRegionName);logger.info("当前输出的文件路径名: "+outFile.getAbsolutePath());// 获取当前region块对应的内部扫描器InternalScanner scanner = hRegion.getScanner(scan);List<KeyValue> results = new ArrayList<KeyValue>();// 每次next拿到的都是同一个row对应的数据while(scanner.next(results)){// do what you want to do here !
}scanner.close();flag = true;return flag;}}

2)再来介绍客户端代码

2.1. 客户端主要是通过RPC拿到指定协处理器实例并调用WriteFile方法,拿到方法的返回值
public class HBaseWriteFileClient {    <span style="white-space:pre"></span>private static final Logger logger = Logger.getLogger(HBaseWriteFileClient.class);    /**     * main方法     * @param args     * 0:导出HBase表名     * 1:导出文件路径     * 2:HMaster IP     * 3:ZK IP     * @throws Throwable     */public static void main(String[] args) throws Throwable {//初始化configurationConfiguration conf = HBaseConfiguration.create();            conf.set("hbase.zookeeper.quorum", zkIP);    <span style="white-space:pre"></span>conf.set("hbase.zookeeper.property.clientPort", "2181");    <span style="white-space:pre"></span>conf.set("hbase.master", hmasterIP);    <span style="white-space:pre"></span>conf.setLong("hbase.rpc.timeout", Integer.MAX_VALUE);HTableInterface table = new HTable(conf, tableName);Scan scan = new Scan();Map<byte[], Boolean> results = table.coprocessorExec(WriteFileProtocol.class,   scan.getStartRow(),   scan.getStopRow(),   new Batch.Call<WriteFileProtocol, Boolean>() {            @Override            public Boolean call(WriteFileProtocol instance) throws IOException {            return instance.writeFile(outFilePath);            }        });}}

3)部署

先将上面代码导出jar包,并把jar包拷贝到每个HBase集群节点中$HBASE_HOME/lib目录下。我这里由于要针对多张HBase表导出数据,所以直接在hbase-site.xml中指定协处理器,做全局协处理器注册。

<property><name>hbase.coprocessor.region.classes</name><value>com.fh.coprocessor.WriteFileCoprocessor</value></property>

4)重启hbase集群

加载自定义协处理器jar包,如果在60010端口页面上发现每个region块中都标记有WriteFileCoprocessor,那么则说明协处理器注册成功。

5)测试

直接在客户端代码HBaseWriteFileClient类中设置好参数,运行main方法,即可成功调用服务端的WriteFile方法,实现数据写出文件功能。也可以在HRegionServer节点日志中关注协处理器调用过程。






0 0
原创粉丝点击