事前準備
AWSのIAMでS3に書き込み可能なアクセスキーとシークレットキーを発行しておいてください。
概要
hadoopコマンドでHDFSからAWSのS3へデータコピーする例です。
コマンド例のディレクトリ名などは以下のようになっていますので読み替えてください。
HDFSディレクトリ | hdfsdir |
---|---|
S3バケット名 | s3bucket |
S3ディレクトリ | s3dir |
S3アクセスキー | S3_ACCESS_KEY_ID |
S3シークレットキー | S3_SECRET_ACCESS_KEY |
コマンド例
distcp
の場合
hadoop distcp \ hdfs:///hdfsdir \ s3a://S3_ACCESS_KEY_ID:S3_SECRET_ACCESS_KEY@s3bucket/s3dir
fs -cp
の場合
hadoop fs -cp \ hdfs:///hdfsdir \ s3a://S3_ACCESS_KEY_ID:S3_SECRET_ACCESS_KEY@s3bucket/s3dir
TIPS
Hadoopのバージョンの違いから↓の書き方じゃないと構文エラーになる時があります。
上記コマンドでエラーになる場合は以下を試してください。
hadoop distcp \ -Dfs.s3a.access.key=S3_ACCESS_KEY_ID \ -Dfs.s3a.secret.key=S3_SECRET_ACCESS_KEY \ hdfs://hdfsdir s3a://s3bucket/s3dir
distcp
とfs -cp
の違い
distcp
は分散コピーfs -cp
は単体サーバーでコピー
- データが多い場合
distcp
のほうが速く転送出来る - データが少ない場合
fs -cp
のほうが早い場合もあり
シークレットキーに/
スラッシュが入るとエラーになる
シークレットキーにスラッシュが入ったら再作成するしかありません。
エラーは以下のような内容が出力されます。
With failures, global counters are inaccurate; consider running with -i Copy failed: java.lang.NullPointerException: null uri host. This can be caused by unencoded / in the password string at java.util.Objects.requireNonNull(Objects.java:228) at org.apache.hadoop.fs.s3native.S3xLoginHelper.buildFSURI(S3xLoginHelper.java:69) at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:185) at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2816) at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:98) at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2853) at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2835) at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:387) at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296) at org.apache.hadoop.tools.DistCp.setup(DistCp.java:1061) at org.apache.hadoop.tools.DistCp.copy(DistCp.java:678) at org.apache.hadoop.tools.DistCp.run(DistCp.java:895) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84) at org.apache.hadoop.tools.DistCp.main(DistCp.java:922)