Hadoop 在运行 terasort 时崩溃了?

标签 hadoop mapreduce hdfs hadoop-yarn

我正在使用 Hadoop 单节点,稍后可能会转向多节点。现在同一个节点既是主节点又是从节点,因此 namenodedatanode resource managernode 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/

相关文章:

hadoop - 使用元组的字段加载 pig 文件

java - 如何使用 Spark 并行化列表列表?

hadoop - 为所有节点在 hdfs 中复制数据是否更快?

Eclipse MapReduce 插件错误 : Server IPC version 7 cannot cannot communicate with client version 3

hadoop - 添加多个表和文件作为 Hadoop 作业的输入

eclipse - Eclipse在Windows上的Hadoop

hadoop - 使用$ HIVE METASTORE JARS指定指向正确的配置单元jar的有效路径,或将spark.sql.hive.metastore.version更改为1.2.1。

java - Hadoop 单节点集群 - 进程未运行

python - 如何使用 lxml 检查每个元素中的 xmlns

hadoop - 将数据存储在hdfs中而不是消息队列中