phoenix提供了BulkLoad工具,使得用户可以将大数据量的csv格式数据高效地通过phoenix导入hbase,那么phoenix是否也存在高效导出csv数据的工具类呢?
这里可能有人会想是否能够按照导出常规hbase的方法来导出数据。比如自己写Java代码,或者用hbase原生支持的工具类,或者说采用pig提供的hbase工具类。是否能这么干取决于你phoenix建表时候字段的数据类型。如果字段采用的不是varchar、char等字符类型以及unsigned_*类型,或者你的表是salted table,那么脱离phoenix的导出方式必然会导致导出的数据不正确。原因在于phoenix处理大部分数据类型数据字节格式化的方式与原生hbase不一样。比如,phoenix salted table会在rowkey的第一个字节插入hash值来使数据均匀分布到每一个region上,所以用常规hbase导出工具导出势必造成rowkey的导出不正确。
【温馨提示】
phoenix对于INTEGER、LONG等数据类型的序列化方式与原生HBase对于数据的序列化方式不一致。HBase会使用org.apache.hadoop.hbase.util.Bytes
类来进行数据的序列化和反序列化。那么,如果使用phoenix定义了上述数据类型(相当于使用phoenix自己的API来序列化数据到HBase),然后通过HBase原生工具类来导出数据(相当于使用HBase自己的API来反序列化数据),那么在反序列化得到真实数据的时候必然会导致数据错乱。
幸运的是phoenix官方确实提供了一个高效的导出工具类,但是必须依赖于pig。而且在试验过程,也就发现只有这个唯一的工具可以完美地支持phoenix表数据的导出。
关于pig的介绍以及使用不是这篇文章的重点,没有接触过的朋友请自行百度或者google。
phoenix集成pig的介绍可以在下面的官网链接查看:
https://phoenix.apache.org/pig_integration.html
里面提到了两个工具方法,一个用于海量数据的导入,类似于BulkLoad工具,另外一个工具方法用于海量数据的导出。这里我们关注数据的导出。
导出工具号称为 Pig Loader。根据官网上的介绍:
A Pig data loader allows users to read data from Phoenix backed HBase tables within a Pig script.
意思是我们可以编写pig脚本并使用phoenix-pig(phoenix继承pig的模块)提供的工具类来运行pig脚本实现海量数据的导出。
Pig Loader有两种形式实现导出:
第一种是通过指定hbase表名来导出整个表数据,例如我想导出TEST表的所有记录,那么可以用如下的脚本命令:
A = load 'hbase://table/USER' using org.apache.phoenix.pig.PhoenixHBaseLoader('${zookeeper.quorum}');
需要将${zookeeper.quorum}替换成zookeeper集群机器ip加端口,eg: master,slave1,slave2:2181
当然我们还可以精确控制只导出表的哪几个列:
A = load 'hbase://table/USER/ID,NAME' using org.apache.phoenix.pig.PhoenixHBaseLoader('${zookeeper.quorum}');
上面的脚本表示导出TEST表所有记录,但仅包含ID列和NAME列。
另外一种是通过指定query语句来控制导出的数据:
A = load 'hbase://query/SELECT ID,NAME FROM USER WHERE AGE > 50' using org.apache.phoenix.pig.PhoenixHBaseLoader('${zookeeper.quorum}');
【注意】
使用query语句指定的导出方式存在很大的限制,比如说不能指定GROUP BY , LIMIT , ORDER BY , DISTINCT ;同时也无法指定使用聚合函数,如count,sum等。
下面我们通过两个完整的使用示例介绍两种导出方式的使用。Example1演示指定table方式的导出,而Example2演示指定query方式的导出。
vi example1.pig
REGISTER /data/phoenix-default/phoenix-4.6.0-HBase-1.0-client.jar;
rows = load 'hbase://table/USER' USING org.apache.phoenix.pig.PhoenixHBaseLoader('master,slave1,slave2:2181');
STORE rows INTO 'USER.csv' USING PigStorage(',');
执行shell命令:
pig -x mapreduce example1.pig
vi example2.pig
REGISTER /data/phoenix-default/phoenix-4.6.0-HBase-1.0-client.jar;
rows = load 'hbase://query/SELECT ID,NAME FROM USER' USING org.apache.phoenix.pig.PhoenixHBaseLoader('master,slave1,slave2:2181');
STORE rows INTO 'USER.csv' USING PigStorage(',');
执行shell命令:
pig -x mapreduce example2.pig