2013-04-17 11 views
12

ricevo il seguente errore:Impossibile riportare lo stato per 600 secondi. Uccidere! Stato del procedimento di Hadoop

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

per i miei lavori mappa. Questa domanda è simile a this, this e this. Tuttavia, non voglio aumentare il tempo predefinito prima Hadoop uccide un compito che non segnala il progresso, vale a dire,

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

Invece, voglio riferire periodicamente i progressi utilizzando context.progress(), context.setStatus("Some Message") o context.getCounter(SOME_ENUM.PROGRESS).increment(1) o qualcosa di simile. Tuttavia, questo causa comunque la morte del lavoro. Ecco i frammenti di codice in cui sto tentando di segnalare i progressi. Il mappatore:

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

metodo optimiseFurther all'interno della classe per ottimizzare:

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

l'uscita da un mappatore mostra lo stato viene aggiornato:

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

Tuttavia, il lavoro è ancora essere ucciso dopo il periodo di tempo predefinito. Sto usando il contesto nel modo sbagliato? C'è qualcos'altro che devo fare nella configurazione del lavoro per riportare i progressi con successo?

risposta

7

questo problema è quello di fare con un bug in Hadoop 0.20 cui chiamate a context.setStatus() e context.progress() non vengono presentate alla struttura sottostante (chiama anche i vari contatori non funzionano). È disponibile una patch, quindi l'aggiornamento a una versione più recente di Hadoop dovrebbe risolvere questo problema.

6

Quello che potrebbe accadere è che devi chiamare quei metodi di avanzamento su Reporter stesso che si trova all'interno di Contesto e potrebbe non essere in grado di chiamarlo sul contesto stesso.

Da Cloudera

Relazione progresso

Se i rapporti di attività nessun progresso per 10 minuti (vedere la proprietà mapred.task.timeout) allora sarà ucciso da Hadoop. La maggior parte dei compiti non incontra questa situazione poiché segnalano il progresso in modo implicito leggendo l'input e la scrittura. Tuttavia, alcuni lavori che non elaborano i record in questo modo possono cadere in fallo di questo comportamento e avere le loro attività uccise. Le simulazioni sono un buon esempio, dato che eseguono un sacco di elaborazione intensiva della CPU in ciascuna mappa e in genere scrivono il risultato solo alla fine del calcolo. Dovrebbero essere scritti in modo tale da riportare i progressi su base regolare (più frequentemente che ogni 10 minuti). Ciò può essere ottenuto in vari modi:

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

Grazie per il vostro aiuto! L'ho già letto da Cloudera. Comunque, sto usando la nuova API che usa un oggetto 'Context' invece del vecchio oggetto' Reporter'. – Sam

Problemi correlati