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 时,我们可以创建和使用以下三種類型的函数−

  1. Filter Functions - 过滤器函数用作过滤器语句中的条件。这些函数接受 Pig 值作为输入并返回布尔值。

  2. Eval Functions - Eval 函数用于 FOREACH-GENERATE 语句中。这些函数接受 Pig 值作为输入并返回 Pig 结果。

  3. Algebraic Functions - 代数函数对 FOREACHGENERATE 语句中的内部包起作用。这些函数用于对内部包执行完整的 MapReduce 操作。

Writing UDF’s using Java

要使用 Java 编写 UDF,我们必须集成 Jar 文件 Pig-0.15.0.jar 。在本节中,我们将讨论如何使用 Eclipse 编写示例 UDF。在继续操作之前,请确保已在您的系统中安装了 Eclipse 和 Maven。

按照以下给出的步骤编写 UDF 函数:

  1. 打开 Eclipse 并创建一个新项目(比如 myproject )。

  2. 将新创建的项目转换为 Maven 项目。

  3. 将以下内容复制到 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>
  1. 保存该文件并刷新它。您可以在 Maven Dependencies 部分中找到下载的 Jar 文件。

  2. 使用名称 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 所需的代码。在上述示例中,我们返回代码以将给定列的内容转换为大写。

  1. 在成功编译该类后,右键单击 Sample_Eval.java 文件。它将为您提供一个菜单。选择 export ,如下图所示。

select export
  1. 单击 export 后,您将获得以下窗口。单击 JAR file

click export
  1. 通过单击 Next&gt; 按钮继续操作。您将获得另一个窗口,您需要在其中输入本地文件系统中的路径来存储 Jar 文件。

jar export
  1. 最后,单击 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)