HBaseのデータをHiveからselectする

参考にしたのはこの辺

本家Wiki
https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration

Hortonworksのスライド資料

最初はHiveでselect insertしてHBaseにデータロードする方法を試していたけど、以下のようなエラーが出てうまくいかなかった。

FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.hbase.io.HbaseObjectWritable

なのでHBaseのデータをHiveから外部テーブルとして参照してselectする方法をめもっときます。
なお試したバージョンはHBase 0.94.4, Hive 0.10.0です。

hive-site.xmlで以下のようにhive.aux.jars.pathとhbase.zookeeper.quorumを設定します。

    <property>
        <name>hive.aux.jars.path</name>
        <value>...,file:///usr/local/hive/lib/hive-hbase-handler-0.10.0.jar,file:///usr/local/hbase/hbase-0.94.4.jar,file:///usr/local/hbase/lib/zookeeper-3.4.5.jar,file:///usr/local/hbase/lib/protobuf-java-2.4.0a.jar</value>
    </property>
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>...</value>
    </property>

HBaseは以下のようにtesttableテーブルを作ってデータを投入しておきます。column familyはcf1にしています。

hbase(main):048:0> create 'testtable', 'cf1'
0 row(s) in 1.0460 seconds

hbase(main):049:0> put 'testtable', '1', 'cf1:a', 'a'
0 row(s) in 0.0160 seconds

hbase(main):050:0> put 'testtable', '1', 'cf1:b', 'b'
0 row(s) in 0.0040 seconds

hbase(main):051:0> scan 'testtable'
ROW                                                                   COLUMN+CELL
 1                                                                    column=cf1:a, timestamp=1362479322147, value=a
 1                                                                    column=cf1:b, timestamp=1362479325365, value=b
1 row(s) in 0.0120 seconds

上記HBaseのテーブルをHiveから見えるように外部テーブルを下記のように作成します。

CREATE EXTERNAL TABLE testtable(key int, a string, b string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:a,cf1:b")
TBLPROPERTIES ("hbase.table.name" = "testtable");

hbase.table.nameの部分でHBaseのテーブルを指定し、hbase.columns.mappingの部分でHBaseとHiveのカラムのマッピング情報を指定します。:keyはrow keyですね。

そして下記のようにselectすると結果が得られます。

$ hive -e "select * from testtable"
1       a       b

単純なselect *だとMapReduceは実行されないので下記のようにcount(*)するの試してみました。

$ hive -e "select count(*) from testtable"
1

ちなみにhive-site.xmlのhive.aux.jars.pathにprotobuf-java-2.4.0a.jarが無いとselect *はうまくいってもcount(*)で下記のようにエラーになりました。

Error: java.lang.ClassNotFoundException: com.google.protobuf.Message

いじょ。