使用 Apache Pig 处理数据
使用 Apache Pig 从大数据集中得到所需的信息html
Hadoop 的普及和其生态系统的不断壮大并不使人感到意外。Hadoop 不断进步的一个特殊领域是 Hadoop 应用程序的编写。虽然编写 Map 和 Reduce 应用程序并不十分复杂,但这些编程确实须要一些软件开发经验。Apache Pig 改变了这种情况,它在 MapReduce 的基础上建立了更简单的过程语言抽象,为 Hadoop 应用程序提供了一种更加接近结构化查询语言 (SQL) 的接口。所以,您不须要编写一个单独的 MapReduce 应用程序,您能够用 Pig Latin 语言写一个脚本,在集群中自动并行处理与分发该脚本。正则表达式
Pig Latin 示例
让咱们从一个简单的 Pig 示例开始介绍,并剖析该示例。Hadoop 的一个有趣的用法是,在大型数据集中搜索知足某个给定搜索条件的记录(在 Linux® 中被称为 grep
)。清单 1 显示了在 Pig 中实现该过程的简单性。在所显示的三行代码中,只有一行是真正的搜索。第一行只是将测试数据集(消息日志)读取到表明元组集合的包中。用一个正则表达式来筛选该数据(元组中的唯一条目,表示为 $0
或 field 1),而后查找字符序列 WARN
。最后,在主机文件系统中将这个包存储在一个名为 warnings 的新文件中,这个包如今表明来自消息的包含 WARN
的全部元组。shell
清单 1. 一个简单的 Pig Latin 脚本
1
2
3
|
messages = LOAD 'messages';
warns = FILTER messages BY $0 MATCHES '.*WARN+.*';
STORE warns INTO 'warnings';
|
如您所见,这个简单的脚本实现了一个简单的流,可是,若是直接在传统的 MapReduce 模型中实现它,则须要增长大量的代码。这使得学习 Hadoop 并开始使用数据比原始开发容易得多。数据库
如今让咱们更深刻地探讨 Pig 语言,而后查看该语言的一些功能的其余示例。apache
Pig Latin 的基础知识
Pig Latin 是一个相对简单的语言,它能够执行语句。一调语句 就是一个操做,它须要输入一些内容(好比表明一个元组集的包),并发出另外一个包做为其输出。一个包 就是一个关系,与表相似,您能够在关系数据库中找到它(其中,元组表明行,而且每一个元组都由字段组成)。编程
用 Pig Latin 编写的脚本每每遵循如下特定格式,从文件系统读取数据,对数据执行一系列操做(以一种或多种方式转换它),而后,将由此产生的关系写回文件系统。您能够在 清单 1 中看到该模式的最简单形式(一个转换)。安全
Pig 拥有大量的数据类型,不只支持包、元组和映射等高级概念,还支持简单的数据类型,如 int
、long
、float
、double
、chararray
和 bytearray
。若是使用简单的类型,您会发现,除了称为 bincond
的条件运算符(其操做相似于 C ternary
运算符)以外,还有其余许多算术运算符(好比 add
、subtract
、multiply
、divide
和 module
)。而且,如您所指望的那样,还有一套完整的比较运算符,包括使用正则表达式的丰富匹配模式。bash
全部 Pig Latin 语句都须要对关系进行操做(并被称为关系运算符)。正如您在 清单 1 中看到的,有一个运算符用于从文件系统加载数据和将数据存储到文件系统中。有一种方式能够经过迭代关系的行来 FILTER
数据。此功能经常使用于从后续操做再也不须要的关系中删除数据。另外,若是您须要对关系的列进行迭代,而不是对行进行迭代,您可使用 FOREACH
运算符。FOREACH
容许进行嵌套操做,如 FILTER
和 ORDER
,以便在迭代过程当中转换数据。网络
ORDER
运算符提供了基于一个或多个字段对关系进行排序的功能。JOIN
运算符基于公共字段执行两个或两个以上的关系的内部或外部联接。SPLIT
运算符提供了根据用户定义的表达式将一个关系拆分红两个或两个以上关系的功能。最后,GROUP
运算符根据某个表达式将数据分组成为一个或多个关系。表 1 提供了 Pig 中的部分关系运算符列表。
表 1. Pig Latin 关系运算符的不完整列表
虽然这不是一个详尽的 Pig Latin 运算符清单,但该表提供了一套在处理大型数据集时很是有用的操做。您能够经过 参考资料 了解完整的 Pig Latin 语言,由于 Pig 有一套不错的在线文档。如今尝试着手编写一些 Pig Latin 脚本,以了解这些运算符的实际工做状况。
得到 Pig
在有关 Hadoop 的早期文章中,我采用的方法是将 Hadoop 安装和配置为一个软件包。但 Cloudera 经过用 Linux 将它打包为一个虚拟设备,使得 Hadoop 更易于使用。虽然它是一个较大的下载,但它已预创建并配置了虚拟机 (VM),其中不只有 Hadoop,还包括了 Apache Hive 和 Pig。所以,利用一个下载和免费提供的 2 型虚拟机管理程序(VirtualBox 或基于内核的虚拟机 [KVM]),您即可以拥有预配置的、已准备就绪的整个 Hadoop 环境。
让 Hadoop 和 Pig 启动并运行
下载完您的特定虚拟机文件以后,须要为您的特定虚拟机管理程序建立一个 VM。在 参考资料 中,您能够找到该操做的分步指南。
一旦建立了本身的 VM,就能够经过 VirtualBox 来启动它,VirtualBox 引导 Linux 内核,并启动全部必要的 Hadoop 守护进程。完成引导后,从建立一个与 Hadoop 和 Pig 通讯的终端开始相关操做。
您能够在两种模式中任选一种来使用 Pig。第一种是 Local(本地)模式,它不须要依赖 Hadoop 或 Hadoop 分布式文件系统 (HDFS),在该模式中,全部操做都在本地文件系统上下文中的单一 Java 虚拟机 (JVM) 上执行。另外一种模式是 MapReduce 模式,它使用了 Hadoop 文件系统和集群。
Local 模式的 Pig
对于 Local 模式,只需启动 Pig 并用 exectype
选项指定 Local 模式便可。这样作能够将您带入 Grunt 外壳,使您可以以交互方式输入 Pig 语句:
1
2
3
|
$ pig -x local
...
grunt>
|
在这里,您可以以交互方式编写 Pig Latin 脚本的代码,并查看每一个运算符后面的结果。返回 清单 1,并尝试使用这个脚本(参见 清单 2)。注意,在这种状况下,不须要将数据存储到某个文件中,只需将它转储为一组关系。您可能会在修改后的输出中看到,每一个日志行(与 FILTER
定义的搜索条件相匹配)自己就是一个关系(以括号 [()
] 为界)。
清单 2. 在 Local 模式中以交互方式使用 Pig
1
2
3
4
5
6
7
|
grunt> messages = LOAD '/var/log/messages';
grunt> warns = FILTER messages BY $0 MATCHES '.*WARN+.*';
grunt> DUMP warns
...
(Dec 10 03:56:43 localhost NetworkManager: <
WARN
> nm_generic_enable_loopback(): error ...
(Dec 10 06:10:18 localhost NetworkManager: <
WARN
> check_one_route(): (eth0) error ...
grunt>
|
若是您已经指定 STORE
运算符,那么它会在一个指定名称的目录(而不是一个简单的常规文件)中生成您的数据。
Mapreduce 模式中的 Pig
对于 MapReduce 模式,必须首先确保 Hadoop 正在运行。要作到这一点,最简单的方法是在 Hadoop 文件系统树的根上执行文件列表操做,如 清单 3 所示。
清单 3. 测试 Hadoop 可用性
1
2
3
4
5
6
|
$ hadoop dfs -ls /
Found 3 items
drwxrwxrwx - hue supergroup 0 2011-12-08 05:20 /tmp
drwxr-xr-x - hue supergroup 0 2011-12-08 05:20 /user
drwxr-xr-x - mapred supergroup 0 2011-12-08 05:20 /var
$
|
如清单 3 所示,若是 Hadoop 成功运行,此代码的结果会是一个或多个文件组成的列表。如今,让咱们来测试 Pig。从启动 Pig 开始,而后将目录更改成您的 HDFS 根,以肯定在 HDFS 中是否能够看到外部所看到的结果(参见 清单 4)。
清单 4. 测试 Pig
1
2
3
4
5
6
7
8
9
10
11
12
|
$ pig
2011-12-10 06:39:44,276 [main] INFO org.apache.pig.Main - Logging error messages to...
2011-12-10 06:39:44,601 [main] INFO org.apache.pig.... Connecting to hadoop file \
system at: hdfs://0.0.0.0:8020
2011-12-10 06:39:44,988 [main] INFO org.apache.pig.... connecting to map-reduce \
job tracker at: 0.0.0.0:8021
grunt> cd hdfs:///
grunt> ls
hdfs://0.0.0.0/tmp <
dir
>
hdfs://0.0.0.0/user <
dir
>
hdfs://0.0.0.0/var <
dir
>
grunt>
|
到目前为止,一切都很好。您能够在 Pig 中看到您的 Hadoop 文件系统,因此,如今请尝试从您的本地主机文件系统将一些数据读取到 HDFS 中。能够经过 Pig 将某个文件从本地复制到 HDFS(参见 清单 5)。
清单 5. 得到一些测试数据
1
2
3
4
5
|
grunt> mkdir test
grunt> cd test
grunt> copyFromLocal /etc/passwd passwd
grunt> ls
hdfs://0.0.0.0/test/passwd<
r
1> 1728
|
接下来,在 Hadoop 文件系统中测试数据如今是安全的,您能够尝试另外一个脚本。请注意,您能够在 Pig 内 cat
文件,查看其内容(只是看看它是否存在)。在这个特殊示例中,将肯定在 passwd 文件中为用户指定的外壳数量(在 passwd 文件中的最后一列)。
要开始执行该操做,须要从 HDFS 将您的 passwd 文件载入一个 Pig 关系中。在使用 LOAD
运算符以前就要完成该操做,但在这种状况下,您可能但愿将密码文件的字段解析为多个独立的字段。在本例中,咱们指定了 PigStorage
函数,您可使用它来显示文件的分隔符(本例中,是冒号 [:
] 字符)。您也能够用 AS
关键字指定独立字段(或架构),包括它们的独立类型(参见 清单 6)。
清单 6. 将文件读入一个关系中
1
2
3
4
5
6
7
8
9
|
grunt> passwd = LOAD '/etc/passwd' USING PigStorage(':') AS (user:chararray, \
passwd:chararray, uid:int, gid:int, userinfo:chararray, home:chararray, \
shell:chararray);
grunt> DUMP passwd;
(root,x,0,0,root,/root,/bin/bash)
(bin,x,1,1,bin,/bin,/sbin/nologin)
...
(cloudera,x,500,500,,/home/cloudera,/bin/bash)
grunt>
|
接下来,使用 GROUP
运算符根据元组的外壳将元组分组到该关系中(参见 清单 7)。再次转储此关系,这样作只是为了说明 GROUP
运算符的结果。注意,在这里,您须要根据元组正使用的特定外壳(在开始时指定的外壳)对元组进行分组(做为一个内部包)。
清单 7. 将元组分组为其外壳的一个函数
1
2
3
4
5
6
|
grunt> grp_shell = GROUP passwd BY shell;
grunt> DUMP grp_shell;
(/bin/bash,{(cloudera,x,500,500,,/home/cloudera,/bin/bash),(root,x,0,0,...), ...})
(/bin/sync,{(sync,x,5,0,sync,/sbin,/bin/sync)})
(/sbin/shutdown,{(shutdown,x,6,0,shutdown,/sbin,/sbin/shutdown)})
grunt>
|
可是,您想要的是在 passwd 文件中指定的独特外壳的计数。因此,须要使用 FOREACH
运算符来遍历分组中的每一个元组,COUNT
出现的数量(参见 清单 8)。
清单 8. 利用每一个外壳的计数对结果进行分组
1
2
3
4
5
6
7
8
9
10
|
grunt> counts = FOREACH grp_shell GENERATE group, COUNT(passwd);
grunt> DUMP counts;
...
(/bin/bash,5)
(/bin/sync,1)
(/bin/false,1)
(/bin/halt,1)
(/bin/nologin,27)
(/bin/shutdown,1)
grunt>
|
备注:若是要将该代码做为一个脚原本执行,只需将脚本输入到某个文件中,而后使用 pig myscript.pig
来执行它。
诊断运算符
Pig 支持大量诊断运算符,您能够用它们来调试 Pig 脚本。正如您在以前的脚本示例中所看到的,DUMP
运算符是无价的,它不只能够查看数据,还能够查看数据架构。您还可使用 DESCRIBE
运算符来生成一个关系架构的详细格式(字段和类型)。
EXPLAIN
运算符更复杂一些,但也颇有用。对于某个给定的关系,您可使用 EXPLAIN
来查看如何将物理运算符分组为 Map 和 Reduce 任务(也就是说,如何推导出数据)。
表 2 对 Pig Latin 中的诊断运算符及其描述提供了一个列表。
表 2. Pig Latin 诊断运算符
用户定义的函数
虽然 Pig 在本文探讨的范围内是强大且有用的,可是经过用户定义的函数 (UDF) 可使它变得更强大。Pig 脚本可使用您为解析输入数据、格式化输出数据甚至运算符等定义的函数。UDF 是用 Java 语言编写的,容许 Pig 支持自定义处理。UDF 是将 Pig 扩展到您的特定应用程序领域的一种方式。您能够在 参考资料 中了解有关 UDF 开发的更多信息。
Pig 用户
正如您从这篇短文中能够看到的,Pig 是一个强大的工具,能够在 Hadoop 集群中查询数据。它是如此强大,Yahoo! 估计,其 Hadoop 工做负载中有 40% 至 60% 由 Pig Latin 脚本产生。在 Yahoo! 的 100,000 个 CPU 中,大约有 50% 的 CPU 仍在运行 Hadoop。
但 Yahoo! 并非利用 Pig 的唯一组织。您在 Twitter 中也会发现 Pig(用于处理日志和挖掘微博数据);在 AOL 和 MapQuest 上也会发现它(用于分析和批量数据处理);而在 LinkedIn 上,Pig 用于发现您可能认识的人。据报道,Ebay 使用 Pig 来实现搜索优化,而 adyard 的推荐工具系统有大约一半都使用了 Pig。
展望将来
没有一本书能够彻底列举 Pig 背后处理大数据的强大功能。即便对于非开发人员而言,Pig 也可使得执行 Hadoop 集群上的大数据处理变得很容易。Pig 最初是由 Yahoo! 于 2006 年开发,而且此后不久被迁移到 Apache Software Foundation,使得它在全球范围获得普遍应用。进行这种迁移是由于 Yahoo! 研究人员意识到 Pig 能为非开发人员提供强大的功能。Hadoop 做为一个基础架构已经逐渐开始普及,Hadoop 生态系统将会改变大数据的外观及其日益增加的使用状况。
相关主题
- Apache 网站 是有关 Pig 的信息来源,包括时事新闻、最新的软件、如何入门和如何参与。
- Hadoop Demo VM 是目前使 Hadoop 实例运行的最简单方式。该 VM 中包含了您所需的一切,包括 Hadoop、Hive 和一个 CentOS Linux 操做系统上的 Pig。
- Cloudera Training VM 是一个极佳的 Hadoop 入门方式。它最大限度地减小所需的配置量,让您能够轻松地开始利用 Hadoop 和 Pig 处理数据集。
- 虚拟设备和 Open Virtualization Format(M. Tim Jones,developerWorks,2009 年 10 月)探讨了将虚拟设备用做一种新的软件交付形式。虚拟设备容许将预配置软件(带操做系统)做为一个 VM 进行分发。
- Pig 有大量的在线资源,包括参考手册、操做手册和其余参考资料。Pig 也有两本写得很好的手册(第 1 部分 和 第 2 部分)、一本 脚本操做手册 和一本 UDF 指南。
- 拥有由重要的 Web 资产所组成的庞大用户群。在 Apache 的 PoweredBy 页面上了解使用 Pig 的多种 Web 企业。
- 在 developerWorks Linux 专区 中,查找数百篇 指南文章和教程,还有下载、论坛,以及针对 Linux 开发人员和管理员的丰富资源。
- developerWorks 中国网站开源技术专区 提供了有关开源工具和使用开源技术的丰富信息。
- 以最适合您的方式 IBM 产品评估试用版软件:下载产品试用版,在线试用产品,在云环境下试用产品,或者在 IBM SOA 人员沙箱 中花费几个小时来学习如何高效实现面向服务架构。
- 在 developerWorks Linux 专区 寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅咱们 最受欢迎的文章和教程。
- 在 developerWorks 上查阅全部 Linux 技巧 和 Linux 教程。
- 随时关注 developerWorks 技术活动和网络广播。