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

Hadoop 在EvalFunc pig UDF中抛出异常是跳过该行,还是完全停止?,hadoop,apache-pig,Hadoop,Apache Pig,我有一个用Java编写的用户定义函数(UDF),用于解析日志文件中的行并将信息返回给pig,这样它就可以完成所有处理 它看起来像这样: public abstract class Foo extends EvalFunc<Tuple> { public Foo() { super(); } public Tuple exec(Tuple input) throws IOException { try {

我有一个用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);
        }
    }
}
通过此输入:

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

它会处理这两行并且“日志”会有两个元组,还是会在火灾中死亡?

如果UDF抛出异常,任务将失败并重试

它将再次失败三次(默认情况下尝试四次),整个作业将失败

如果要记录错误并且不希望停止作业,可以返回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;

在我的例子中,我还在UDF中定义了一个模式,因此通过返回null,结果元组中的所有内容都将为null,对吗?那么如何过滤它呢?按a筛选事件不为NULL,假设EvalFunc在无法找出“a”时始终返回NULL?您需要根据UDF返回的字段名称进行筛选。在本例中,其名称为“line”,其值可以为“null”或“(1,2,3)”。因此,您需要执行“按行筛选事件不为null”,如第一个示例所示。如果返回的元组包含3个空字段,例如,(,)而不是“空”,则可以执行“按行筛选事件。a不为空”,但它不那么简单。@Romain是否可以将日志存储在某个位置,以跟踪在某些行触发的异常?
events = FOREACH events_all GENERATE line.a;