我正在尝试使用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
答案 0 :(得分:2)
我们在尝试将Apache Spark(版本1.5.2)的运行结果直接保存到S3时遇到了类似的异常。但例外是相同的。我不确定核心问题是什么 - 不知何故,S3上传似乎并没有“好玩”#34;使用Hadoop的LocalDirAllocator类(版本2.7)。
最终为我们解决的是以下各项的组合:
启用S3&#34;快速上传&#34; - 通过设置&#34; fs.s3a.fast.upload&#34;到&#34;真&#34;在Hadoop配置中。这使用S3AFastOutputStream而不是S3AOutputStream并直接从内存上传数据,而不是先分配本地存储
在保存到s3之前将作业结果合并到单个部分(在Spark中称为重新分区/合并)
但有些警告:
S3的快速上传显然已被标记为&#34;实验&#34;在Hadoop 2.7
此解决方法仅适用于较新的s3a文件系统(&#34; s3a://...")。它不会为年长的&#34;本地人&#34; s3n文件系统(&#34; s3n://...&#34;)
希望这会有所帮助
答案 1 :(得分:1)
理想情况下,您应该使用s3a而不是s3n,因为不推荐使用s3n。
使用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,请确保它有足够的空间,并且应该有希望解决这个问题。
答案 2 :(得分:0)
我有几天都遇到此错误,但没有得到所发生的一切,所有节点都具有PLENTY空间(大约400GB)。 经过研究,我发现了这一点: 2019-01-09 17:31:30,326警告[main] org.apache.hadoop.fs.LocalDirAllocator $ AllocatorPerContext:无法创建/ mnt / hadoop / tmp / s3a
该异常说明了空间,但真正的错误是权限,该消息可以得到改善。
答案 3 :(得分:0)
使用Hadoop 2.8.5时,我遇到了同样的问题,但是将"fs.s3a.fast.upload"
设置为"true"
并不能解决问题。我还必须将fs.s3a.fast.upload.buffer
设置为"bytebuffer"
。 fs.s3a.fast.upload.buffer
的默认设置为"disk"
,这说明了为什么我仍然遇到相同的错误。还有一个"array"
设置,但我没有尝试过。
可用的fs.s3a.fast.upload.buffer
设置是:
bytebuffer已缓冲到JVM堆外内存。
array已缓冲到JVM堆内存。
disk [默认]缓冲到本地硬盘。
在上面链接的Hadoop站点上都有每个警告的说明。
下面的pySpark示例代码。
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
sc = spark.sparkContext
hdpConf = sc._jsc.hadoopConfiguration()
user = os.getenv("USER")
hdpConf.set("hadoop.security.credential.provider.path", "jceks://hdfs/user/{}/awskeyfile.jceks".format(user))
hdpConf.set("fs.s3a.fast.upload", "true")
hdpConf.set("fs.s3a.fast.upload.buffer", "bytebuffer")