Pig 的 UDF 中存在“in”会导致问题
Posted
技术标签:
【中文标题】Pig 的 UDF 中存在“in”会导致问题【英文标题】:Presence of "in" in Pig's UDF causes problems 【发布时间】:2015-06-02 17:04:16 【问题描述】:我在 pig 中尝试了我的第一个 UDF,并编写了以下函数 -
package com.pig.in.action.assignments.udf;
import org.apache.pig.EvalFunc;
import org.apache.pig.PigWarning;
import org.apache.pig.data.Tuple;
import java.io.IOException;
public class CountLength extends EvalFunc<Integer>
public Integer exec(Tuple inputVal) throws IOException
// Validate Input Value ...
if (inputVal == null ||
inputVal.size() == 0 ||
inputVal.get(0) == null)
// Emit warning text for user, and skip this iteration
super.warn("Inappropriate parameter, Skipping ...",
PigWarning.SKIP_UDF_CALL_FOR_NULL);
return null;
// Count # of characters in this string ...
final String inputString = (String) inputVal.get(0);
return inputString.length();
但是,当我尝试按如下方式使用它时,Pig 会抛出一条错误消息,至少在我的 UDF 上下文中对我来说不容易理解:
grunt> cat dept.txt;
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
grunt> dept = LOAD '/user/sgn/dept.txt' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
grunt> d = FOREACH dept GENERATE dept_no, com.pig.in.action.assignments.udf.CountLength(d_name);
2015-06-02 16:24:13,416 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <line 2, column 79> mismatched input '(' expecting SEMI_COLON
Details at logfile: /home/sgn/pig_1433261973141.log
谁能帮我弄清楚这是怎么回事?
我浏览了文档,但对我来说,上面的示例中似乎没有什么明显的错误。我在这里错过了什么吗?
这些是我在 pom.xml 中使用的库:
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
有兼容性问题吗?
谢谢,
-维普尔帕塔克;
【问题讨论】:
在使用 udf 之前使用 REGISTER yourjar.jar 执行命令之前是否注册了 jar? 是的 Murali,Jar 已注册。 【参考方案1】:在停机大约 36 小时后找到问题的原因...
包名中包含“IN”,这对 Pig 来说是个问题。
package com.pig.in.action.assignments.udf;
// ^^
当我将包名更改为以下时,一切都很好 -
package com.pig.nnn.action.assignments.udf;
// ^^^
在构建修改后的 UDF 后,我注册了 Jar 并为函数名和宾果游戏定义了一个别名,一切正常 -
REGISTER /user/sgn/UDFs/Pig/CountLength-1.jar;
DEFINE CL com.pig.nnn.action.assignments.udf.CountLength;
. . .
. . .
d = FOREACH dept GENERATE dept_no, CL(d_name) AS DeptLength;
我不记得 IN 是否是 Pig 中的保留词。但仍然存在 IN 会导致问题,(至少在 Pig 的 0.14.0 版本中)。
【讨论】:
IN 子句在 pig 的 v 0.12 中引入。参考:hortonworks.com/blog/announcing-apache-pig-0-12。对这个问题的根本原因感到惊讶:) 是的...Pig 对这类关键字有疑问...曾经必须对此很在意...干得好人...【参考方案2】:试过上面的例子。只要使用 REGISTER 命令注册 jar 并且 jar 在类路径中可用,我们就不会看到任何错误。
REGISTER myudfs.jar;
dept = LOAD 'a.csv' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
d = FOREACH dept GENERATE dept_no, CountLength(d_name) as length;
输入:a.csv
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
输出:d
(10,10)
(20,8)
(30,5)
(40,10)
注意: 在上面的运行中,类 CountLength 已在默认包中定义。
如果此类 - CountLength 已在包 com.pig.utility 中定义,那么要访问 UDF,我们必须有如下的 DEFINE 语句
DEFINE CountLength com.pig.utility.CountLength;
或
我们必须通过完整的路径来引用UDF,如下所示:
d = FOREACH dept GENERATE dept_no, com.pig.utility.CountLength(d_name) as length;
【讨论】:
除非您为其定义别名,否则您在调用它时也需要包含该包:DEFINE CountLength com.pig.in.action.assignments.udf.CountLength();
@Balduz :同意如果我们在包中有 CountLength 类,我们需要有 DEFINE 声明。在上面的测试运行中,我在默认包中定义了类 CountLength,因为不需要 DEFINE 语句。
感谢@Balduz 和 Murali,我已经尝试了这些步骤,但我完全不知道为什么它不适合我。它抱怨 '(' 并说应该是 SEMI_COLON。
发现问题。请。检查下面的详细信息。【参考方案3】:
您的 jar 应该已注册 例如:
REGISTER /home/hadoop/udf.jar;
DEFINE package.CountLength CountLength ;
【讨论】:
谢谢阿曼,就像我在上面评论的那样,我已经执行了这两个步骤,并尝试了各种组合,将我的 JAR 放在不同的位置、更改 Jar 的名称、将 Jar 放在 HDFS 中等等。似乎没有工作。我怀疑应该是一些非常愚蠢的原因......但是具有讽刺意味的是,我看不出我的 UDF 未被识别的原因。 发现问题。请。检查下面的详细信息。以上是关于Pig 的 UDF 中存在“in”会导致问题的主要内容,如果未能解决你的问题,请参考以下文章
鉴于我将 DataBag 溢出到磁盘,为啥此 Pig UDF 会导致“错误:Java 堆空间”?