2010-03-29 3 views
6

Ho una User Defined Function (UDF) scritta in Java per analizzare le righe in un file di registro e restituire informazioni al maiale, in modo che possa eseguire tutta l'elaborazione.Il lancio di un'eccezione in un UDF di EvalFunc pig salta solo quella linea o si interrompe completamente?

Sembra qualcosa di simile a questo:

public abstract class Foo extends EvalFunc<Tuple> { 
    public Foo() { 
     super(); 
    } 

    public Tuple exec(Tuple input) throws IOException { 
     try { 
      // do stuff with input 
     } catch (Exception e) { 
      throw WrappedIOException.wrap("Error with line", e); 
     } 
    } 
} 

La mia domanda è: se si lancia l'IOException, si fermerà completamente, o sarà restituirà i risultati per il resto delle linee che non un'eccezione ?

Esempio: eseguire questo nel maiale

REGISTER myjar.jar 
DEFINE Extractor com.namespace.Extractor(); 

logs = LOAD '$IN' USING TextLoader AS (line: chararray); 
events = FOREACH logs GENERATE FLATTEN(Extractor(line)); 

Con questo ingresso:

1.5 7 "Valid Line" 
1.3 gghyhtt Inv"alid line"" I throw an exceptioN!! 
1.8 10 "Valid Line 2" 

Intende elaborare le due linee e sara 'log' avere 2 tuple, o sarà solo morire in un fuoco?

risposta

8

Se l'eccezione viene lanciata dall'UDF, l'attività avrà esito negativo e verrà ritentata.

Fallirà ancora altre tre volte (4 tentativi per impostazione predefinita) e l'intero processo sarà FALLITO.

Se si desidera registrare l'errore e non vogliono avere il lavoro interrotto è possibile restituire un valore nullo:

public Tuple exec(Tuple input) throws IOException { 
    try { 
     // do stuff with input 
    } catch (Exception e) { 
     System.err.println("Error with ..."); 
     return null; 
    } 
} 

e filtrare in un secondo momento in Pig:

events_all = FOREACH logs GENERATE Extractor(line) AS line; 
events_valid = FILTER events_all by line IS NOT null; 
events = FOREACH events_valid GENERATE FLATTEN(line); 

Nel tuo esempio l'output avrà solo le due linee valide (ma fai attenzione a questo comportamento in quanto l'errore è presente solo nei log e non fallirà il tuo lavoro!).

Rispondi al commento # 1:

In realtà, l'intera risultante tupla sarebbe nullo (quindi non c'è nessun campo interno).

Per esempio, se lo schema ha 3 campi:

events_all = FOREACH logs 
       GENERATE Extractor(line) AS line:tuple(a:int,b:int,c:int); 

e alcune linee non sono corretti otterremmo:

() 
((1,2,3)) 
((1,2,3)) 
() 
((1,2,3)) 

E se non filtrare la linea di nulla e tenta di accedere un campo si ottiene un java.lang.NullPointerException:

events = FOREACH events_all GENERATE line.a; 
+0

Nel mio caso , Definisco anche uno schema nell'UDF, quindi restituendo null, tutto nella tuple risultante sarebbe nullo, corretto? –

+0

Come si filtra allora? FILTER eventi BY a IS NOT NULL, assumendo che EvalFunc restituisca sempre null se non riesce a capire 'a'? –

+0

È necessario filtrare il nome del campo restituito da UDF. Nel nostro caso il suo nome è "line" ei suoi valori potrebbero essere "null" o "(1,2,3)". Così si esegue un 'FILTRO eventi per riga NON è null' come mostrato nel primo esempio Pig. Se si restituisce una tupla con 3 campi null, ad es. '(,,)' invece di 'null' potresti fare 'FILTER events BY line.a IS NOT NULL' ma è meno semplice. – Romain

Problemi correlati