HBaseでバルクロード

Hadoop関連(全部俺) Advent Calendar 2014:20日目の記事です
HBase徹底入門ももうすぐ発売される予定、HBaseの1.0.0RCも公開され、盛り上がってきました。HBaseのバルクロードを検証したときのメモを紹介します。

HBaseのバルクロード

HBaseにデータを初期投入する場合など、大量のデータをデータのロードが必要な場合があります。例えばRDBMS からのデータをインポートしたい場合には Sqoop を利用することができます。
Sqoop User Guide: 7.2.11. Importing Data Into HBase
しかし、大量のデータをロードする場合は、メムストアが頻繁にフラッシュされてしまい、結果として頻繁にコンパクションが生じる可能性があります。大量のデータの場合はリージョン分割が生じたり、シーケンシャルや時系列データでは、ひとつのリージョンサーバーに書き込みが集中してホットスポットになるかもしれません。また、WALへの書き込み(無効化可能)によるオーバーヘッドや、GCが生じる場合もあります。
幸いなことにHBaseにはバルクロードツールがあり、このツールはMapReduceでHBaseの使用するファイル形式である HFile を直接作成、ロードできるので効率的です。今回は少々古いブログ [*1]を参考にして、Quickstart VMを使ってバルクロードしてみます。

サンプルデータをダウンロード

ブログを参考にサンプルデータをダウンロードします。
[shell]
$ mkdir hbase
$ cd hbase
$ curl -O https://people.apache.org/~jdcryans/word_count.csv
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7217 100 7217 0 0 9225 0 –:–:– –:–:– –:–:– 46262
[/shell]

HDFSにアップロード

ダウンロードしたデータをHDFSにアップロードします。
[shell]
$ hdfs dfs -put word_count.csv
[/shell]

テーブルを作成

今回ダウンロードしたデータをロードするテーブルを作成します。事前スプリットするので5つのリージョンになっています。
[shell]
$ hbase shell
hbase(main):001:0> create ‘wordcount’, {NAME=>’f’}, {SPLITS=> [‘g’,’m’,’r’,’w’]}
0 row(s) in 6.8120 seconds
=> Hbase::Table – wordcount
[/shell]

importtsvツールでファイルに書き出す

データの区切り文字はカンマ(,)出力ファイルは output 、列ファミリーは f です。
MapReduceが実行されるので、しばらく待ちます。
[shell]
$ hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator=, -Dimporttsv.bulk.output=output -Dimporttsv.columns=HBASE_ROW_KEY,f:count wordcount word_count.csv
[/shell]
終わったらHBaseのファイルを見てみましょう。5つのファイルが作成されていますね。
[shell]
$ hadoop fs -ls hbase_output/f
Found 5 items
-rw-r–r– 1 cloudera cloudera 10200 2014-12-18 04:07 hbase_output/f/3274221fee9244db991495c94ab78cc2
-rw-r–r– 1 cloudera cloudera 2382 2014-12-18 04:07 hbase_output/f/6b14c11ecb6e4284aa804f4a858a6bc1
-rw-r–r– 1 cloudera cloudera 7467 2014-12-18 04:07 hbase_output/f/85b1893d8e5547a8a4c862a36f3cdd50
-rw-r–r– 1 cloudera cloudera 5528 2014-12-18 04:07 hbase_output/f/cad677d9bc934e45a70e1dcff3cffaf1
-rw-r–r– 1 cloudera cloudera 6310 2014-12-18 04:07 hbase_output/f/e11b041276ed4115afddae8464f824c6
[/shell]

パーミッションの変更

HDFSのファイルの所有者を変更しておきます。これをやらないとバルクロード時にエラーになります。
[shell]
$ sudo -u hdfs hdfs dfs -chown -R hbase:hbase /user/cloudera/hbase_output
[/shell]

バルクロードの実行

[shell]
$ hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles hbase_output wordcount
14/12/18 04:18:09 INFO zookeeper.RecoverableZooKeeper: Process identifier=hconnection-0x2376f91f connecting to ZooKeeper ensemble=quickstart.cloudera:2181
14/12/18 04:18:09 INFO zookeeper.ZooKeeper: Client environment:zookeeper.version=3.4.5-cdh5.2.0–1, built on 10/11/2014 20:49 GMT
14/12/18 04:18:09 INFO zookeeper.ZooKeeper: Client environment:host.name=quickstart.cloudera
14/12/18 04:18:09 INFO zookeeper.ZooKeeper: Client environment:java.version=1.7.0_67
14/12/18 04:18:09 INFO zookeeper.ZooKeeper: Client environment:java.vendor=Oracle Corporation
14/12/18 04:18:09 INFO zookeeper.ZooKeeper: Client environment:java.home=/usr/java/jdk1.7.0_67-cloudera/jre
 (略)
14/12/18 04:18:12 INFO mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://quickstart.cloudera:8020/user/cloudera/hbase_output/f/3274221fee9244db991495c94ab78cc2 first=a last=from
14/12/18 04:18:12 INFO mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://quickstart.cloudera:8020/user/cloudera/hbase_output/f/6b14c11ecb6e4284aa804f4a858a6bc1 first=w last=yourself
14/12/18 04:18:12 INFO mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://quickstart.cloudera:8020/user/cloudera/hbase_output/f/85b1893d8e5547a8a4c862a36f3cdd50 first=r last=vms
14/12/18 04:18:12 INFO mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://quickstart.cloudera:8020/user/cloudera/hbase_output/f/cad677d9bc934e45a70e1dcff3cffaf1 first=m last=quickstart
14/12/18 04:18:12 INFO mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://quickstart.cloudera:8020/user/cloudera/hbase_output/f/e11b041276ed4115afddae8464f824c6 first=g last=lot
$
[/shell]
最後にテーブルのデータの一部を見てみます。データがインポートされていますね。
[shell]
hbase(main):003:0> scan ‘wordcount’, {LIMIT=>10}
ROW COLUMN+CELL
a column=f:count, timestamp=1418904392951, value=53
able column=f:count, timestamp=1418904392951, value=1
about column=f:count, timestamp=1418904392951, value=1
access column=f:count, timestamp=1418904392951, value=1
according column=f:count, timestamp=1418904392951, value=3
across column=f:count, timestamp=1418904392951, value=1
added column=f:count, timestamp=1418904392951, value=1
additional column=f:count, timestamp=1418904392951, value=1
adds column=f:count, timestamp=1418904392951, value=1
advanced column=f:count, timestamp=1418904392951, value=1
10 row(s) in 0.0310 seconds
hbase(main):004:0>
[/shell]

余談:Spark on HBase

SparkOnHBaseのブログ[*2]に従って Spark on HBase を試してみましたが、Quickstart VM環境では mvn clean package でエラーが出てしまってうまくいかず。リベンジがうまくいけばブログに書くかもしれません。
 

[*1] How-to: Use HBase Bulk Loading, and Why

[*2] New in Cloudera Labs: SparkOnHBase

コメント