我正在使用 Hadoop 单节点,稍后可能会转向多节点。现在同一个节点既是主节点又是从节点,因此 namenode
、datanode
resource manager
和 node manager
是在同一台 PC 上运行。
每当我在安装在 /home/hadoop/hdfs
上的单独测试磁盘上触发 terasort
(这里 hadoop
是用户名)时,它都会失败出现以下错误:
INFO mapreduce.Job: Task Id : attempt_1429766544852_0001_m_001255_0, Status : FAILED
Error: org.apache.hadoop.util.DiskChecker$DiskErrorException: Could not find any valid local directory for attempt_1429766544852_0001_m_001255_0_spill_1.out
at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:398)
at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:150)
at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:131)
at org.apache.hadoop.mapred.YarnOutputFiles.getSpillFileForWrite(YarnOutputFiles.java:159)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1573)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1467)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.close(MapTask.java:699)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:769)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)
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:1491)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)
15/04/23 11:36:07 INFO mapreduce.Job: Task Id : attempt_1429766544852_0001_m_001258_0, Status : FAILED
Error: java.io.IOException: No space left on device
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:345)
at org.apache.hadoop.fs.RawLocalFileSystem$LocalFSFileOutputStream.write(RawLocalFileSystem.java:236)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at org.apache.hadoop.mapred.IFile$Writer.close(IFile.java:163)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1633)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.access$900(MapTask.java:852)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$SpillThread.run(MapTask.java:1510)
Error: java.io.IOException: No space left on device
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:345)
at org.apache.hadoop.fs.RawLocalFileSystem$LocalFSFileOutputStream.write(RawLocalFileSystem.java:236)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at org.apache.hadoop.mapred.IFile$Writer.close(IFile.java:163)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1633)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.access$900(MapTask.java:852)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$SpillThread.run(MapTask.java:1510)
Error: java.io.IOException: Spill failed
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.checkSpillException(MapTask.java:1540)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.access$300(MapTask.java:852)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$Buffer.write(MapTask.java:1352)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$Buffer.write(MapTask.java:1329)
at java.io.DataOutputStream.writeByte(DataOutputStream.java:153)
at org.apache.hadoop.io.WritableUtils.writeVLong(WritableUtils.java:273)
at org.apache.hadoop.io.WritableUtils.writeVInt(WritableUtils.java:253)
at org.apache.hadoop.io.Text.write(Text.java:323)
at org.apache.hadoop.io.serializer.WritableSerialization$WritableSerializer.serialize(WritableSerialization.java:98)
at org.apache.hadoop.io.serializer.WritableSerialization$WritableSerializer.serialize(WritableSerialization.java:82)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1127)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:691)
at org.apache.hadoop.mapreduce.task.TaskInputOutputContextImpl.write(TaskInputOutputContextImpl.java:89)
at org.apache.hadoop.mapreduce.lib.map.WrappedMapper$Context.write(WrappedMapper.java:112)
at org.apache.hadoop.mapreduce.Mapper.map(Mapper.java:124)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:763)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)
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:1491)
基本上,溢出失败
、磁盘检查器
、没有剩余空间
等
当我调查这个问题时,在单独的终端中继续运行 df -h
给出了线索,它正在使用 /
目录进行某些内部操作,因为作业处于进步。当 /
上没有剩余空间时,作业失败。
我尝试将 hadoop.tmp.dir
更改为其他已安装的磁盘。它工作正常,但再次失败,因为该磁盘也没有足够的空间。
我的问题是为什么会发生这种情况,我们可以完全避免这个问题吗?或者,在 .xml
配置文件中配置哪些确切参数,以便将其限制在 RAM
内或使用磁盘空间,但确保不会使作业失败并使用任何空间它已经崩溃了,但没有因为我提到的任何错误而崩溃?
提前致谢。
PS:我研究了几乎所有的配置参数,并进行了大致各种尝试和尝试,但仍然失败了。所以,我想到这里来问一下,希望你能帮忙。
最佳答案
My question is why is it happening
因此,为了让您更好地理解,Mapper 一旦任务完成,中间输出就会溢出到磁盘(由 yarn.nodemanager.local-dirs
指定,其默认值为 ${hadoop.tmp.dir}/nm-local-dir
),当然,如果数据不适合映射器的内存,那么也会产生溢出,并在任务结束时合并并写入最终返回磁盘。
类似地,reducer 必须将中间数据从 Mapper 的本地文件系统复制到它自己的本地文件系统来处理数据。
因此,例如,如果您使用 4 个映射器和一个缩减器对 100G 数据运行 terasort,然后假设您的映射器已生成 25G 中间数据,则缩减器在其本地文件系统上必须有 100G 可用空间来处理它。
can we avoid this issue at all?
在您的情况下,增加任务不会有帮助,因为它是一台机器。
避免该问题的唯一方法是添加更多 NodeManager,以便您可以从该节点获得更多磁盘空间来处理作业。
what exact parameters be configured in .xml config files so that to restrict it to within RAM
您不能限制 MapReduce 作业仅使用 RAM,因为要进行洗牌过程,数据必须写入磁盘。
or use disk space but make sure not to fail the job and use whatever space it has but don't crash due to any error which I have mentioned?
您的集群上必须有足够的磁盘空间用于中间任务的输出,才能处理作业。
关于Hadoop 在运行 terasort 时崩溃了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29816754/