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 堆空间”?

是否可以在 pig java udf 中使用 pig 内置函数

Pig 中的 Python UDF

Pig的Python UDF:数据类型转换错误

Pig 版本和 UDF

Pig:加入后字段不存在