代码之家  ›  专栏  ›  技术社区  ›  Eduardo León

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

  •  6
  • Eduardo León  · 技术社区  · 16 年前

    我有一个用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);
            }
        }
    }
    

    我的问题是:如果它抛出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"
    

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

    1 回复  |  直到 16 年前
        1
  •  8
  •   Romain    16 年前

    如果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);
    

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

    例如,如果您的架构有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;
    
    推荐文章