CDH の HBase データを Amazon EMR に移行する
Cloudera Hadoop (CDH) の HBase データを Amazon EMR に移行する検証をしているのですが、ベストプラクティスがわからず苦戦しました。 @kuborn さんにいろいろ教えてもらって、これで行けるだろうという手順が確立できたので公開します。
大まかな流れは、こんな感じです。
- CDH の Master ノードで hbase コマンドを使ってデータをエクスポートする。
- HDFS 上のファイルを Linux のファイルシステムにコピーする。
- 2 番のファイルを EMR の Master ノードに転送する。
- Linux 上のファイルを HDFS のファイルシステムにコピーする。
- HBase シェルでテーブルを作成する。
- hbase コマンドを使ってデータをインポートする。
データのエクスポート
hbase コマンドを使って、テーブル単位でエクスポートします。
hoge テーブルを HDFS 上の /tmp/hoge にエクスポートする
$ hbase org.apache.hadoop.hbase.mapreduce.Driver export hoge /tmp/hoge
エクスポートすると HDFS 上に SequenceFile 形式として書き出されます。
$ hadoop dfs -ls /tmp/hoge
Found 3 items
-rw-r--r-- 1 hadoop supergroup 0 2014-03-04 01:09 /tmp/hoge/_SUCCESS
drwxr-xr-x - hadoop supergroup 0 2014-03-04 01:09 /tmp/hoge/_logs
-rw-r--r-- 1 hadoop supergroup 245413734 2014-03-04 01:09 /tmp/hoge/part-m-00000
hadoop コマンドに hbase.jar を渡すやり方でも同じことができますが、HADOOP_CLASSPATH 変数の設定が必要だったり、EMR の hbase.jar には MANIFEST.MF に Main-Class の記述がなかったりでハマりました。
HDFS 上のファイルをコピー
先ほどエクスポートしたファイルは HDFS 上に存在するのでローカルにコピーします。コピーしたら HDFS 上のファイルは消しておきます。
$ hadoop dfs -get /tmp/hoge .
$ hadoop dfs -rmr /tmp/hoge
このあと EMR の Master ノードに転送するので、データサイズが大きい場合は tar で固めるなりしてください。
Master ノードに転送
EMR のクラスタを立ち上げて Master ノードにファイルを転送します。
$ scp hoge.tar.gz hadoop@ec2-xxx-xxx-xxx-xxx.ap-southeast-1.compute.amazonaws.com:~
ログインユーザーは ec2-user ではなく hadoop です。ここで、またハマりました。
Linux 上のファイルをコピー
転送したファイルを展開して HDFS 上にコピーします。
$ hadoop dfs -put hoge /tmp
テーブルの作成
インポートする前に HBase シェルでテーブルを作成します。 DDL はそれぞれ読み替えてください。
$ hbase shell
> create 'foo', {NAME => 'bar', ...}
データのインポート
エクスポートの逆の手順で HDFS 上のファイルをインポートします。うまくいけば MapReduce の進捗が標準出力に流れます。
HDFS 上の /tmp/hoge を hoge テーブルにインポートする
$ hbase org.apache.hadoop.hbase.mapreduce.Driver import hoge /tmp/hoge
14/03/06 08:49:11 INFO mapred.JobClient: Default number of map tasks: null
14/03/06 08:49:11 INFO mapred.JobClient: Setting default number of map tasks based on cluster size to : 6
14/03/06 08:49:11 INFO mapred.JobClient: Default number of reduce tasks: 0
14/03/06 08:49:12 INFO security.ShellBasedUnixGroupsMapping: add hadoop to shell userGroupsCache
14/03/06 08:49:12 INFO mapred.JobClient: Setting group to hadoop
14/03/06 08:49:12 INFO input.FileInputFormat: Total input paths to process : 1
...
あとは HBase シェルの list
, count
, scan
などで正しく移行できたか検証してください。
$ echo "list" | hbase shell
$ echo "count 'hoge'" | hbase shell
$ echo "scan 'hoge'" | hbase shell
まとめ
ググってもほとんど情報がないので、ここに辿り着くまでにかなり試行錯誤しました。 EMR を利用することで運用コストは下がると思いますが、移行はなかなか大変です。
もっと良い方法があれば、ぜひ教えてください :-)