Не удалось сообщить статус в течение 600 секунд. Убивать! Отчет о прогрессе в hadoop

Я получаю следующую ошибку:

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

для моих заданий Map. Этот вопрос похож на этот, этот и этот. Однако Я не хочу увеличивать время по умолчанию до того, как hasoop убивает задачу, которая не сообщает о прогрессе, т.е.

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);
}

метод optimizeFurther в классе Optimiser:

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
...

Однако работа по-прежнему убивается после установленного по умолчанию времени. Я использую контекст неправильно? Есть ли что-то еще, что мне нужно сделать в настройке задания, чтобы сообщить о достигнутом прогрессе?

Ответ 1

Эта проблема связана с ошибкой в Hadoop 0.20, в которой вызовы context.setStatus() и context.progress() не сообщаются в базовую структуру (вызовы для установки разные счетчики тоже не работают). Доступен патч, поэтому обновление до более новой версии Hadoop должно исправить это.

Ответ 2

Что может случиться, так это то, что вы должны называть эти методы прогресса самим Репортером, который находится в Контексте, и не может его вызывать по самому контексту.

От Cloudera

Прогресс отчета

Если ваша задача не сообщает о прогрессе в течение 10 минут (см. свойство mapred.task.timeout), то он будет убит Hadoop. Большинство задач не сталкиваются с этой ситуацией, поскольку они сообщают о прогрессе неявно, читая ввод и запись вывода. Тем не менее, некоторые задания, которые не обрабатывают записи таким образом, могут нарушить это поведение и убить их задачи. Моделирование - хороший пример, поскольку на каждой карте они выполняют большую интенсивную обработку процессора и обычно записывают результат только в конце вычисления. Они должны быть написаны таким образом, чтобы сообщать о прогрессе на регулярной основе (чаще, чем каждые 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

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