Пропускает ли исключение в EvalFunc pig UDF только эту строку или полностью останавливается? - PullRequest
6 голосов
/ 29 марта 2010

У меня есть пользовательская функция (UDF), написанная на Java для анализа строк в файле журнала и возврата информации обратно в pig, чтобы она могла выполнять всю обработку.

Это выглядит примерно так:

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

У меня вопрос: если он выдает IOException, он полностью остановится или вернет результаты для остальных строк, которые не выдают исключение?

Пример: я запускаю это на свинье

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

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

С этим входом:

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

Будет ли он обрабатывать две строки, и будут ли 'журналы' иметь 2 кортежа, или он просто умрет в огне?

1 Ответ

8 голосов
/ 30 марта 2010

Если UDF выдает исключение, задание не будет выполнено и будет повторена.

Снова произойдет сбой еще три раза (по умолчанию 4 попытки), и все задание будет ОТКАЗАНО.

Если вы хотите зарегистрировать ошибку и не хотите, чтобы работа была остановлена, вы можете вернуть ноль:

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

И отфильтровать их позже в 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);

В вашем примере выходные данные будут иметь только две допустимые строки (но будьте осторожны с этим поведением, поскольку ошибка присутствует только в журналах и не подведет вашу работу!).

Ответ на комментарий # 1:

На самом деле, весь результирующий кортеж будет нулевым (поэтому внутри полей нет).

Например, если ваша схема имеет 3 поля:

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

и некоторые строки неверны, мы получили бы:

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

И если вы не отфильтруете пустую строку и не попытаетесь получить доступ к полю, вы получите java.lang.NullPointerException :

events = FOREACH events_all GENERATE line.a;
...