3

distcp を使用して、ローカルの Hadoop クラスターから S3 バケットにデータをコピーしようとしています。

「うまくいく」こともありますが、一部のマッパーは失敗し、以下のスタック トレースが表示されます。また、非常に多くのマッパーが失敗し、ジョブ全体がキャンセルされることもあります。

「どのローカル ディレクトリにも空き容量がありません」というエラーが表示されます。私には意味がありません。エッジ ノード (distcp コマンドが実行されている場所)、クラスター、および S3 バケットには十分なスペースがあります。

誰でもこれに光を当てることができますか?

16/06/16 15:48:08 INFO mapreduce.Job: The url to track the job: <url>
16/06/16 15:48:08 INFO tools.DistCp: DistCp job-id: job_1465943812607_0208
16/06/16 15:48:08 INFO mapreduce.Job: Running job: job_1465943812607_0208
16/06/16 15:48:16 INFO mapreduce.Job: Job job_1465943812607_0208 running in uber mode : false
16/06/16 15:48:16 INFO mapreduce.Job:  map 0% reduce 0%
16/06/16 15:48:23 INFO mapreduce.Job:  map 33% reduce 0%
16/06/16 15:48:26 INFO mapreduce.Job: Task Id : attempt_1465943812607_0208_m_000001_0, Status : FAILED
Error: java.io.IOException: File copy failed: hdfs://<hdfs path>/000000_0 --> s3n://<bucket>/<s3 path>/000000_0
        at org.apache.hadoop.tools.mapred.CopyMapper.copyFileWithRetry(CopyMapper.java:285)
        at org.apache.hadoop.tools.mapred.CopyMapper.map(CopyMapper.java:253)
        at org.apache.hadoop.tools.mapred.CopyMapper.map(CopyMapper.java:50)
        at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:146)
        at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:787)
        at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:415)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1709)
        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
Caused by: java.io.IOException: Couldn't run retriable-command: Copying hdfs://<hdfs path>/000000_0 to s3n://<bucket>/<s3 path>/000000_0
        at org.apache.hadoop.tools.util.RetriableCommand.execute(RetriableCommand.java:101)
        at org.apache.hadoop.tools.mapred.CopyMapper.copyFileWithRetry(CopyMapper.java:281)
        ... 10 more
Caused by: org.apache.hadoop.util.DiskChecker$DiskErrorException: No space available in any of the local directories.
        at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:366)
        at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.createTmpFileForWrite(LocalDirAllocator.java:416)
        at org.apache.hadoop.fs.LocalDirAllocator.createTmpFileForWrite(LocalDirAllocator.java:198)
        at org.apache.hadoop.fs.s3native.NativeS3FileSystem$NativeS3FsOutputStream.newBackupFile(NativeS3FileSystem.java:263)
        at org.apache.hadoop.fs.s3native.NativeS3FileSystem$NativeS3FsOutputStream.<init>(NativeS3FileSystem.java:245)
        at org.apache.hadoop.fs.s3native.NativeS3FileSystem.create(NativeS3FileSystem.java:412)
        at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:986)
        at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.copyToFile(RetriableFileCopyCommand.java:174)
        at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doCopy(RetriableFileCopyCommand.java:123)
        at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doExecute(RetriableFileCopyCommand.java:99)
        at org.apache.hadoop.tools.util.RetriableCommand.execute(RetriableCommand.java:87)
        ... 11 more
4

4 に答える 4

2

Apache Spark (バージョン 1.5.2) から S3 への実行結果を直接保存しようとしたときに、同様の例外が発生しました。例外は同じですが。中心的な問題が何であるかはよくわかりません.Hadoop の LocalDirAllocator クラス (バージョン 2.7) では、S3 のアップロードがうまくいかないようです。

最終的に解決したのは、次の組み合わせでした。

  1. Hadoop 設定で「fs.s3a.fast.upload」を「true」に設定することにより、S3 の「高速アップロード」を有効にします。これは、S3AOutputStream の代わりに S3AFastOutputStream を使用し、最初にローカル ストレージを割り当てる代わりに、メモリから直接データをアップロードします。

  2. s3 に保存する前に、ジョブの結果を単一の部分にマージします (Spark では、再分割/合体と呼ばれます)。

ただし、いくつかの注意事項があります。

  1. S3 の高速アップロードは、 Hadoop 2.7では明らかに「実験的」とマークされています

  2. この回避策は、新しい s3a ファイル システム ("s3a://...") にのみ適用されます。古い「ネイティブ」s3n ファイルシステム (「s3n://...」) では機能しません。

お役に立てれば

于 2016-07-04T15:14:56.743 に答える
2

s3n は非推奨であるため、理想的には s3n ではなく s3a を使用する必要があります。

s3a には、次のパラメーターがあります。

<property>
  <name>fs.s3a.buffer.dir</name>
  <value>${hadoop.tmp.dir}/s3a</value>
  <description>Comma separated list of directories that will be used to buffer file
uploads to. No effect if fs.s3a.fast.upload is true.</description>
</property>

ローカル ファイル エラーが発生する場合は、バッファ ディレクトリにスペースがないことが原因である可能性があります。

この設定を変更して、より多くのスペースのあるディレクトリを指すようにすることもできますが、より良い解決策は次のように設定することです (これも S3a で):

fs.s3a.fast.upload=真

これにより、ローカル ディスク上のデータのバッファリングが回避され、実際には高速になるはずです。

S3n バッファ ディレクトリ パラメータは次のようになります。

fs.s3.buffer.dir

したがって、s3n を使い続ける場合は、十分なスペースがあることを確認してください。うまくいけば、この問題が解決するはずです。

于 2017-09-12T09:57:21.223 に答える