Мне записали Определяемую пользователем функцию (UDF) в Java для парсинга строк в файле журнала и информации о возврате назад свинье, таким образом, это может сделать всю обработку.
Это выглядит примерно так:
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 кортежа, или это просто умрет в огне?
Если UDF выбрасывает исключение, задача завершится ошибкой и будет повторена.
Еще три раза произойдет сбой (по умолчанию 4 попытки), и все задание будет ЗАВЕРШЕНО.
Если вы хотите зарегистрировать ошибку и не хотите, чтобы задание было остановлено, вы можете вернуть значение null:
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;