CDH の HBase データを Amazon EMR に移行する

Posted on

Cloudera Hadoop (CDH) の HBase データを Amazon EMR に移行する検証をしているのですが、ベストプラクティスがわからず苦戦しました。 @kuborn さんにいろいろ教えてもらって、これで行けるだろうという手順が確立できたので公開します。

大まかな流れは、こんな感じです。

  1. CDH の Master ノードで hbase コマンドを使ってデータをエクスポートする。
  2. HDFS 上のファイルを Linux のファイルシステムにコピーする。
  3. 2 番のファイルを EMR の Master ノードに転送する。
  4. Linux 上のファイルを HDFS のファイルシステムにコピーする。
  5. HBase シェルでテーブルを作成する。
  6. 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 を利用することで運用コストは下がると思いますが、移行はなかなか大変です。

もっと良い方法があれば、ぜひ教えてください :-)