无法报告状态600秒。杀!报告hadoop的进展情况

时间:2013-04-17 09:42:58

标签: java hadoop mapreduce

我收到以下错误:

Task attempt_201304161625_0028_m_000000_0 failed to report status for 600 seconds. Killing! 

我的地图工作。此问题类似于thisthisthis。但是,我不希望在hadoop杀死一个没有报告进度的任务之前增加默认时间,即

Configuration conf=new Configuration();
long milliSeconds = 1000*60*60;
conf.setLong("mapred.task.timeout", milliSeconds);

相反,我想使用context.progress()context.setStatus("Some Message")context.getCounter(SOME_ENUM.PROGRESS).increment(1)或类似内容定期报告进度。然而,这仍然导致工作被杀死。以下是我尝试报告进度的代码片段。映射器:

protected void map(Key key, Value value, Context context) throws IOException, InterruptedException {

    //do some things
    Optimiser optimiser = new Optimiser();
    optimiser.optimiseFurther(<some parameters>, context);
    //more things
    context.write(newKey, newValue);
}

Optimiser类中的optimiseFurther方法:

public void optimiseFurther(<Some parameters>, TaskAttemptContext context) {

    int count = 0;
    while(something is true) {
        //optimise

        //try to report progress
        context.setStatus("Progressing:" + count);
        System.out.println("Optimise Progress:" + context.getStatus());
        context.progress();
        count++;
    }
}

映射器的输出显示状态正在更新:

Optimise Progress:Progressing:0
Optimise Progress:Progressing:1
Optimise Progress:Progressing:2
...

但是,在默认的时间后,作业仍然被杀死。我是以错误的方式使用上下文吗?我还需要在作业设置中做些什么来成功报告进度吗?

2 个答案:

答案 0 :(得分:7)

此问题与bug in Hadoop 0.20有关,因此不会向基础框架报告对context.setStatus()context.progress()的调用(设置各种计数器的调用也不起作用)。有一个补丁可用,因此更新到更新版本的Hadoop应该可以解决这个问题。

答案 1 :(得分:6)

可能发生的事情是你必须在Contexter中调用那些在Context中找到的进度方法,并且可能无法在上下文本身上调用它。

来自Cloudera

报告进度

如果您的任务在10分钟内没有报告任何进度(请参阅mapred.task.timeout属性),那么它将被Hadoop杀死。大多数任务都不会遇到这种情况,因为它们通过读取输入和写入输出来隐式报告进度。但是,一些不以这种方式处理记录的工作可能会违反这种行为并使其任务被杀死。模拟是一个很好的例子,因为它们在每个映射中执行大量CPU密集型处理,并且通常仅在计算结束时写入结果。它们的编写方式应定期报告进度(每10分钟更频繁一次)。这可以通过多种方式实现:

Call setStatus() on Reporter to set a human-readable description of
the task’s progress
Call incrCounter() on Reporter to increment a user counter
Call progress() on Reporter to tell Hadoop that your task is 
still there (and making progress)

Cloudera Tips

public Context(Configuration conf, TaskAttemptID taskid,
               RecordReader<KEYIN,VALUEIN> reader,
               RecordWriter<KEYOUT,VALUEOUT> writer,
               OutputCommitter committer,
               StatusReporter reporter,
               InputSplit split)