【问题标题】:Hadoop streaming job failure: Task process exit with nonzero status of 137Hadoop 流作业失败:任务进程退出,非零状态为 137
【发布时间】:2011-09-05 19:40:50
【问题描述】:

这几天我一直在研究这个问题,希望有人能提供一些见解。

我在 perl 中编写了一个流式映射 reduce 作业,它很容易让一个或两个 reduce 任务需要很长时间才能执行。这是由于数据中的自然不对称性:一些 reduce 键有超过一百万行,而大多数只有几十行。

我之前遇到过长时间任务的问题,我一直在递增计数器以确保 map reduce 不会超时。但是现在他们失败了,出现了我以前从未见过的错误消息:

java.io.IOException: Task process exit with nonzero status of 137.
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:418)

这不是标准的超时错误消息,但错误代码 137 = 128+9 表明我的减速器脚本从 Hadoop 收到了 kill -9。 tasktracker 日志包含以下内容:

2011-09-05 19:18:31,269 WARN org.mortbay.log: Committed before 410 getMapOutput(attempt_201109051336_0003_m_000029_1,7) failed :
org.mortbay.jetty.EofException
        at org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:787)
        at org.mortbay.jetty.AbstractGenerator$Output.blockForOutput(AbstractGenerator.java:548)
        at org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.java:569)
        at org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:946)
        at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:646)
        at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:577)
        at org.apache.hadoop.mapred.TaskTracker$MapOutputServlet.doGet(TaskTracker.java:2940)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:363)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:533)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:207)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:403)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:522)
Caused by: java.io.IOException: Connection reset by peer
        at sun.nio.ch.FileDispatcher.write0(Native Method)
        at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:72)
        at sun.nio.ch.IOUtil.write(IOUtil.java:43)
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334)
        at org.mortbay.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:169)
        at org.mortbay.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:221)
        at org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:721)
        ... 24 more

2011-09-05 19:18:31,289 INFO org.apache.hadoop.mapred.TaskTracker.clienttrace: src: 10.92.8.202:50060, dest: 10.92.8.201:46436, bytes: 7340032, op: MAPRED_SHUFFLE, cliID: attempt_201109051336_0003_m_000029_1
2011-09-05 19:18:31,292 ERROR org.mortbay.log: /mapOutput
java.lang.IllegalStateException: Committed
        at org.mortbay.jetty.Response.resetBuffer(Response.java:994)
        at org.mortbay.jetty.Response.sendError(Response.java:240)
        at org.apache.hadoop.mapred.TaskTracker$MapOutputServlet.doGet(TaskTracker.java:2963)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:363)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:533)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:207)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:403)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:522)

我一直在浏览论坛,听起来警告通常出现在运行没有错误的作业中,通常可以忽略。该错误使减速器看起来与地图输出失去联系,但我不知道为什么。有人有什么想法吗?

这是一个可能相关的事实:这些冗长的任务使我的工作需要几天的时间,而本来应该只需要几分钟。由于我可以在没有一两个键的输出的情况下生活,因此我尝试在减速器中实现十分钟超时,如下所示:

eval {  
        local $SIG{ALRM} = sub {
            print STDERR "Processing of new merchant names in $prev_merchant_zip timed out...\n";
            print STDERR "reporter:counter:tags,failed_zips,1\n";
            die "timeout";
        };

        alarm 600;

        #Code that could take a long time to execute

        alarm 0;
    };

当我在本地测试脚本时,这个超时代码就像一个魅力,但是在我引入它之后,奇怪的 mapreduce 错误就开始了。但是,故障似乎发生在第一次超时之后,所以我不确定它是否相关。

提前感谢您的帮助!

【问题讨论】:

  • 我忘了说,我用的是hadoop 0.20.2。

标签: streaming hadoop


【解决方案1】:

想到两种可能性:

  1. RAM 使用情况,如果任务使用过多的 RAM,操作系统可能会杀死它(在可怕的交换等之后)。
  2. 您是否在使用任何不可重入库?可能是在库调用中的不合时宜的时间点触发了计时器。

【讨论】:

  • 您能否详细说明第二个 (non-reentrant)?
  • 我会首先检查第一个建议(Linux OOM 杀手),因为返回码 137 是它的签名(SIG_KILL 为 128+9)。确定您是否受到这种情况的影响是相当直接的: egrep -i 'killed process' /var/log/messages ,也在这个答案中开发:stackoverflow.com/a/624868/366749
  • 抱歉 - 错过了这条评论。一些库(几年前我们遇到了 Quest 的 auth 库的问题)不是多线程兼容的,如果它们在活动时切换内核任务,“就会发生“坏事”。
【解决方案2】:

退出代码 137 是臭名昭著的 OOM 杀手的典型标志。您可以使用dmesg 命令轻松检查以下消息:

[2094250.428153] CPU: 23 PID: 28108 Comm: node Tainted: G         C O  3.16.0-4-amd64 #1 Debian 3.16.7-ckt20-1+deb8u2
[2094250.428155] Hardware name: Supermicro X9DRi-LN4+/X9DR3-LN4+/X9DRi-LN4+/X9DR3-LN4+, BIOS 3.2 03/04/2015
[2094250.428156]  ffff880773439400 ffffffff8150dacf ffff881328ea32f0 ffffffff8150b6e7
[2094250.428159]  ffff881328ea3808 0000000100000000 ffff88202cb30080 ffff881328ea32f0
[2094250.428162]  ffff88107fdf2f00 ffff88202cb30080 ffff88202cb30080 ffff881328ea32f0
[2094250.428164] Call Trace:
[2094250.428174]  [<ffffffff8150dacf>] ? dump_stack+0x41/0x51
[2094250.428177]  [<ffffffff8150b6e7>] ? dump_header+0x76/0x1e8
[2094250.428183]  [<ffffffff8114044d>] ? find_lock_task_mm+0x3d/0x90
[2094250.428186]  [<ffffffff8114088d>] ? oom_kill_process+0x21d/0x370
[2094250.428188]  [<ffffffff8114044d>] ? find_lock_task_mm+0x3d/0x90
[2094250.428193]  [<ffffffff811a053a>] ? mem_cgroup_oom_synchronize+0x52a/0x590
[2094250.428195]  [<ffffffff8119fac0>] ? mem_cgroup_try_charge_mm+0xa0/0xa0
[2094250.428199]  [<ffffffff81141040>] ? pagefault_out_of_memory+0x10/0x80
[2094250.428203]  [<ffffffff81057505>] ? __do_page_fault+0x3c5/0x4f0
[2094250.428208]  [<ffffffff8109d017>] ? put_prev_entity+0x57/0x350
[2094250.428211]  [<ffffffff8109be86>] ? set_next_entity+0x56/0x70
[2094250.428214]  [<ffffffff810a2c61>] ? pick_next_task_fair+0x6e1/0x820
[2094250.428219]  [<ffffffff810115dc>] ? __switch_to+0x15c/0x570
[2094250.428222]  [<ffffffff81515ce8>] ? page_fault+0x28/0x30

如果启用了OOM,您可以轻松:

$ cat /proc/sys/vm/overcommit_memory
0

基本上,OOM 杀手试图杀死占用大部分内存的进程。而你probably don't want to disable it

可以使用以下命令完全禁用 OOM 杀手。 不建议在生产环境中这样做,因为如果 内存不足的情况确实会出现,可能会出现意外 行为取决于可用的系统资源和 配置。这种意外行为可能来自 内核恐慌取决于可用的资源 OOM 条件时的内核。

sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf

如果您使用例如cgroups 用于限制内存。当进程超过给定的限制时,它会在没有警告的情况下被杀死。

【讨论】:

    【解决方案3】:

    我收到了这个错误。杀了一天,发现它在代码的某个地方是一个无限循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      相关资源
      最近更新 更多