我有一个用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个元组,还是只会在火中死掉?
如果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)
| 归档时间: |
|
| 查看次数: |
2424 次 |
| 最近记录: |