在EvalFunc pig UDF中抛出异常是否只跳过该行,还是完全停止?

Dan*_*tep 6 hadoop apache-pig

我有一个用Java编写的用户定义函数(UDF)来解析日志文件中的行并将信息返回给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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果它抛出IOException,它会完全停止,还是会返回不抛出异常的其余行的结果?

示例:我在猪中运行

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

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

有了这个输入:

1.5 7 "Valid Line"
1.3 gghyhtt Inv"alid line"" I throw an exceptioN!!
1.8 10 "Valid Line 2"
Run Code Online (Sandbox Code Playgroud)

它会处理这两行并且'log'会有2个元组,还是只会在火中死掉?

Rom*_*ain 8

如果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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在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);
Run Code Online (Sandbox Code Playgroud)

在您的示例中,输出将只有两个有效行(但请注意此行为,因为错误仅出现在日志中并且不会使您的作业失败!).

回复评论#1:

实际上,整个结果元组将为null(因此内部没有字段).

例如,如果您的架构有3个字段:

 events_all = FOREACH logs
              GENERATE Extractor(line) AS line:tuple(a:int,b:int,c:int);
Run Code Online (Sandbox Code Playgroud)

并且我们会得到一些不正确的行:

 ()
 ((1,2,3))
 ((1,2,3))
 ()
 ((1,2,3))
Run Code Online (Sandbox Code Playgroud)

如果你不过滤空行并尝试访问一个字段,你会得到一个java.lang.NullPointerException:

events = FOREACH events_all GENERATE line.a;
Run Code Online (Sandbox Code Playgroud)