Apache Pig 简明教程
Apache Pig - User Defined Functions
除了内置函数,Apache Pig 还广泛支持*U*ser *D*efined *F*unctions (UDF)。使用这些 UDF,我们可以定义自己的函数并使用它们。UDF 支持使用六种编程语言提供,分别是 Java、Jython、Python、JavaScript、Ruby 和 Groovy。
对于编写 UDF,Java 提供了完整支持,而所有其他语言都提供有限的支持。使用 Java,您可以编写涉及处理所有部分的 UDF,如数据加载/存储、列转换和聚合。由于 Apache Pig 是用 Java 编写的,因此使用 Java 语言编写的 UDF 与其他语言相比运行效率更高。
在 Apache Pig 中,我们还有一个名为 Piggybank 的 UDF Java 存储库。使用 Piggybank,我们可以访问其他用户编写的 Java UDF,并贡献自己的 UDF。
Types of UDF’s in Java
在使用 Java 编写 UDF 时,我们可以创建和使用以下三種類型的函数−
-
Filter Functions - 过滤器函数用作过滤器语句中的条件。这些函数接受 Pig 值作为输入并返回布尔值。
-
Eval Functions - Eval 函数用于 FOREACH-GENERATE 语句中。这些函数接受 Pig 值作为输入并返回 Pig 结果。
-
Algebraic Functions - 代数函数对 FOREACHGENERATE 语句中的内部包起作用。这些函数用于对内部包执行完整的 MapReduce 操作。
Writing UDF’s using Java
要使用 Java 编写 UDF,我们必须集成 Jar 文件 Pig-0.15.0.jar 。在本节中,我们将讨论如何使用 Eclipse 编写示例 UDF。在继续操作之前,请确保已在您的系统中安装了 Eclipse 和 Maven。
按照以下给出的步骤编写 UDF 函数:
-
打开 Eclipse 并创建一个新项目(比如 myproject )。
-
将新创建的项目转换为 Maven 项目。
-
将以下内容复制到 pom.xml 中。此文件包含 Apache Pig 和 Hadoop 核心 Jar 文件的 Maven 依赖项。
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0http://maven.apache .org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Pig_Udf</groupId>
<artifactId>Pig_Udf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>0.20.2</version>
</dependency>
</dependencies>
</project>
-
保存该文件并刷新它。您可以在 Maven Dependencies 部分中找到下载的 Jar 文件。
-
使用名称 Sample_Eval 创建一个新类文件,并复制以下内容。
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class Sample_Eval extends EvalFunc<String>{
public String exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
String str = (String)input.get(0);
return str.toUpperCase();
}
}
在编写 UDF 时,必须继承 EvalFunc 类并向 exec() 函数提供实现。在此函数内编写 UDF 所需的代码。在上述示例中,我们返回代码以将给定列的内容转换为大写。
-
在成功编译该类后,右键单击 Sample_Eval.java 文件。它将为您提供一个菜单。选择 export ,如下图所示。
-
单击 export 后,您将获得以下窗口。单击 JAR file 。
-
通过单击 Next> 按钮继续操作。您将获得另一个窗口,您需要在其中输入本地文件系统中的路径来存储 Jar 文件。
-
最后,单击 Finish 按钮。在指定的文件夹中,将创建 Jar 文件 sample_udf.jar 。此 Jar 文件包含用 Java 编写的 UDF。
Using the UDF
在编写 UDF 并生成 Jar 文件后,按照以下给出的步骤操作:
Step 1: Registering the Jar file
在编写 UDF(Java 中)后,我们必须使用 Register 运算符注册包含 UDF 的 Jar 文件。通过注册 Jar 文件,用户可以告知 Apache Pig UDF 的位置。
Syntax
以下是 Register 运算符的语法。
REGISTER path;
Example
作为一个示例,让我们在此章节的前面注册创建的 sample_udf.jar。
在本地模式下启动 Apache Pig 并注册 Jar 文件 sample_udf.jar,如下所示。
$cd PIG_HOME/bin
$./pig –x local
REGISTER '/$PIG_HOME/sample_udf.jar'
Note - 假设路径中为 /$PIG_HOME/sample_udf.jar
Step 2: Defining Alias
在注册 UDF 后,我们可以使用 Define 运算符为其定义别名。
Syntax
下文是 Define 运算符的语法。
DEFINE alias {function | [`command` [input] [output] [ship] [cache] [stderr] ] };
Example
如下所示定义 sample_eval 的别名。
DEFINE sample_eval sample_eval();
Step 3: Using the UDF
定义别名之后,您可以像使用内置函数一样使用 UDF。假设 HDFS /Pig_Data/ 目录中有个名为 emp_data 的文件,其中包含以下内容。
001,Robin,22,newyork
002,BOB,23,Kolkata
003,Maya,23,Tokyo
004,Sara,25,London
005,David,23,Bhuwaneshwar
006,Maggy,22,Chennai
007,Robert,22,newyork
008,Syam,23,Kolkata
009,Mary,25,Tokyo
010,Saran,25,London
011,Stacy,25,Bhuwaneshwar
012,Kelly,22,Chennai
假设我们像下面这样将这个文件载入 Pig。
grunt> emp_data = LOAD 'hdfs://localhost:9000/pig_data/emp1.txt' USING PigStorage(',')
as (id:int, name:chararray, age:int, city:chararray);
现在让我们使用 UDF sample_eval 将员工姓名转换为大写。
grunt> Upper_case = FOREACH emp_data GENERATE sample_eval(name);
如下所示,验证关联 Upper_case 的内容。
grunt> Dump Upper_case;
(ROBIN)
(BOB)
(MAYA)
(SARA)
(DAVID)
(MAGGY)
(ROBERT)
(SYAM)
(MARY)
(SARAN)
(STACY)
(KELLY)