2013-04-17 2 views
12

ich die folgende Fehlermeldung:Fehler beim Melden des Status für 600 Sekunden. Tötung! Berichterstattung über die Fortschritte in hadoop

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

für meine Karte Arbeitsplätze. Diese Frage ähnelt this, this und this. Allerdings Ich will nicht die Standardlaufzeit zu erhöhen, bevor hadoop eine Aufgabe tötet, die nicht Fortschritt, dh

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

Stattdessen meldet, möchte ich regelmäßig, welche Fortschritte berichten entweder context.progress(), context.setStatus("Some Message") oder context.getCounter(SOME_ENUM.PROGRESS).increment(1) oder sowas ähnliches. Dies führt jedoch immer noch dazu, dass der Job beendet wird. Hier sind die Codeschnipsel, in denen ich versuche, den Fortschritt zu melden. Der Mapper:

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

die optimiseFurther Methode innerhalb der Klasse 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++; 
    } 
} 

Die Ausgabe von einem Mapper zeigt der Status aktualisiert wird:

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

Allerdings ist die Arbeit noch nach der Standardzeit getötet werden. Benutze ich den Kontext falsch? Gibt es noch etwas, was ich bei der Job-Einrichtung tun muss, um den Fortschritt erfolgreich zu melden?

Antwort

7

Dieses Problem mit einem bug in Hadoop 0.20 zu tun ist, wodurch Anrufe zu context.setStatus() und context.progress() sind nicht auf den zugrunde liegenden Framework gemeldet (ruft setzen Sie verschiedene Zähler nicht funktionieren auch nicht). Es ist ein Patch verfügbar, daher sollte das Aktualisieren auf eine neuere Version von Hadoop dies beheben.

6

Möglicherweise müssen Sie diese Fortschrittsmethoden auf Reporter selbst aufrufen, die im Kontext gefunden werden und möglicherweise nicht in der Lage sind, den Kontext selbst aufzurufen.

Von Cloudera

Bericht Fortschritte

Wenn Ihre Aufgabe Berichte keinen Fortschritt für 10 Minuten (siehe mapred.task.timeout Eigenschaft), dann wird es von Hadoop getötet werden. Die meisten Tasks treffen nicht auf diese Situation, da sie den Fortschritt implizit durch Lesen der Eingabe- und Schreibausgabe melden. Einige Jobs, die keine Datensätze auf diese Weise verarbeiten, können jedoch dieses Verhalten beeinträchtigen und ihre Aufgaben erledigen. Simulationen sind ein gutes Beispiel, da sie in jeder Map eine Menge CPU-intensiver Verarbeitung durchführen und das Ergebnis in der Regel erst am Ende der Berechnung schreiben. Sie sollten so geschrieben sein, dass der Fortschritt regelmäßig gemeldet wird (häufiger als alle 10 Minuten). Dies kann in einer Reihe von Wegen erreicht werden:

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) 
+0

Danke für Ihre Hilfe! Das habe ich schon von Cloudera gelesen. Allerdings verwende ich die neue API, die ein 'Context'-Objekt anstelle des alten' Reporter'-Objekts verwendet. – Sam

Verwandte Themen