使用 Apache Pig 处理数据

来源:互联网 发布:犀牛5.0破解软件 编辑:程序博客网 时间:2024/05/22 09:02
Hadoop的普及和其生态系统的不断壮大并不令人感到意外。Hadoop不断进步的一个特殊领域是Hadoop应用程序的编写。虽然编写MapReduce应用程序并不十分复杂,但这些编程确实需要一些软件开发经验。ApachePig改变了这种状况,它在MapReduce的基础上创建了更简单的过程语言抽象,为Hadoop应用程序提供了一种更加接近结构化查询语言(SQL)的接口。因此,您不需要编写一个单独的MapReduce应用程序,您可以用PigLatin语言写一个脚本,在集群中自动并行处理与分发该脚本。

Pig Latin示例

让我们从一个简单的 Pig示例开始介绍,并剖析该示例。Hadoop的一个有趣的用法是,在大型数据集中搜索满足某个给定搜索条件的记录(在Linux®中被称为grep)。清单1显示了在Pig中实现该过程的简单性。在所显示的三行代码中,只有一行是真正的搜索。第一行只是将测试数据集(消息日志)读取到代表元组集合的包中。用一个正则表达式来筛选该数据(元组中的惟一条目,表示为$0field1),然后查找字符序列WARN。最后,在主机文件系统中将这个包存储在一个名为warnings的新文件中,这个包现在代表来自消息的包含WARN的所有元组。
清单1. 一个简单的Pig Latin脚本
messages = LOAD 'messages';warns = FILTER messages BY $0 MATCHES '.*WARN+.*';STORE warns INTO 'warnings';
如您所见,这个简单的脚本实现了一个简单的流,但是,如果直接在传统的MapReduce模型中实现它,则需要增加大量的代码。这使得学习Hadoop并开始使用数据比原始开发容易得多。
现在让我们更深入地探讨 Pig语言,然后查看该语言的一些功能的其他示例。


Pig Latin的基础知识可以参考pig官网对piglatin的相关讲解:http://pig.apache.org/docs/r0.10.0/basic.html

PigLatin是一个相对简单的语言,它可以执行语句。一调语句就是一个操作,它需要输入一些内容(比如代表一个元组集的包),并发出另一个包作为其输出。一个就是一个关系,与表类似,您可以在关系数据库中找到它(其中,元组代表行,并且每个元组都由字段组成)。
PigLatin编写的脚本往往遵循以下特定格式,从文件系统读取数据,对数据执行一系列操作(以一种或多种方式转换它),然后,将由此产生的关系写回文件系统。您可以在清单1中看到该模式的最简单形式(一个转换)。
Pig拥有大量的数据类型,不仅支持包、元组和映射等高级概念,还支持简单的数据类型,如intlongfloatdoublechararraybytearray。如果使用简单的类型,您会发现,除了称为bincond的条件运算符(其操作类似于Cternary运算符)之外,还有其他许多算术运算符(比如addsubtractmultiplydividemodule)。并且,如您所期望的那样,还有一套完整的比较运算符,包括使用正则表达式的丰富匹配模式。
所有 PigLatin语句都需要对关系进行操作(并被称为关系运算符)。正如您在清单1中看到的,有一个运算符用于从文件系统加载数据和将数据存储到文件系统中。有一种方式可以通过迭代关系的行来FILTER数据。此功能常用于从后续操作不再需要的关系中删除数据。另外,如果您需要对关系的列进行迭代,而不是对行进行迭代,您可以使用FOREACH运算符。FOREACH允许进行嵌套操作,如FILTERORDER,以便在迭代过程中转换数据。
ORDER运算符提供了基于一个或多个字段对关系进行排序的功能。JOIN运算符基于公共字段执行两个或两个以上的关系的内部或外部联接。SPLIT运算符提供了根据用户定义的表达式将一个关系拆分成两个或两个以上关系的功能。最后,GROUP运算符根据某个表达式将数据分组成为一个或多个关系。表1提供了Pig中的部分关系运算符列表。
1. Pig Latin关系运算符的不完整列表

运算符

描述

FILTER

基于某个条件从关系中选择一组元组。

FOREACH

对某个关系的元组进行迭代,生成一个数据转换。

GROUP

将数据分组为一个或多个关系。

JOIN

联接两个或两个以上的关系(内部或外部联接)。

LOAD

从文件系统加载数据。

ORDER

根据一个或多个字段对关系进行排序。

SPLIT

将一个关系划分为两个或两个以上的关系。

STORE

在文件系统中存储数据。

虽然这不是一个详尽的 PigLatin 运算符清单,但该表提供了一套在处理大型数据集时非常有用的操作。您可以通过参考资料了解完整的PigLatin 语言,因为Pig有一套不错的在线文档。现在尝试着手编写一些PigLatin脚本,以了解这些运算符的实际工作情况。


获得Pig

在 有关 Hadoop的早期文章中,我采用的方法是将Hadoop安装和配置为一个软件包。但Cloudera通过用Linux将它打包为一个虚拟设备,使得Hadoop更易于使用。虽然它是一个较大的下载,但它已预建立并配置了虚拟机(VM),其中不仅有Hadoop,还包括了ApacheHivePig。因此,利用一个下载和免费提供的2型虚拟机管理程序(VirtualBox或基于内核的虚拟机[KVM]),您便可以拥有预配置的、已准备就绪的整个Hadoop环境。


Hadoop Pig 启动并运行

下载完您的特定虚拟机文件之后,需要为您的特定虚拟机管理程序创建一个VM。在参考资料中,您可以找到该操作的分步指南。

Cloudera VM内存

我发现,仅为虚拟机分配 1GB的内存时,它无法正常工作。将该内存分配提高至两倍甚至三倍时,它才能够正常运行(也就是说,不会出现Java™堆内存的问题)。
一旦创建了自己的 VM,就可以通过VirtualBox来启动它,VirtualBox引导Linux内核,并启动所有必要的Hadoop守护进程。完成引导后,从创建一个与HadoopPig通信的终端开始相关操作。
您 可以在两种模式中任选一种来使用 Pig。第一种是Local(本地)模式,它不需要依赖HadoopHadoop分布式文件系统(HDFS),在该模式中,所有操作都在本地文件系统上下文中的单一Java虚拟机(JVM)上执行。另一种模式是MapReduce模式,它使用了Hadoop文件系统和集群。

Local模式的Pig

对于 Local模式,只需启动Pig并用exectype选项指定Local模式即可。这样做可以将您带入Grunt外壳,使您能够以交互方式输入Pig语句:
$ pig -x local...grunt>
在这里,您能够以交互方式编写 PigLatin 脚本的代码,并查看每个运算符后面的结果。返回清单1,并尝试使用这个脚本(参见清单2)。注意,在这种情况下,不需要将数据存储到某个文件中,只需将它转储为一组关系。您可能会在修改后的输出中看到,每个日志行(与FILTER定义的搜索条件相匹配)本身就是一个关系(以括号[()]为界)。
清单2. Local模式中以交互方式使用Pig
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可用性
$ hadoop dfs -ls /Found 3 itemsdrwxrwxrwx   - hue    supergroup          0 2011-12-08 05:20 /tmpdrwxr-xr-x   - hue    supergroup          0 2011-12-08 05:20 /userdrwxr-xr-x   - mapred supergroup          0 2011-12-08 05:20 /var$
如清单 3所示,如果Hadoop成功运行,此代码的结果会是一个或多个文件组成的​​列表。现在,让我们来测试Pig。从启动Pig开始,然后将目录更改为您的HDFS根,以确定在HDFS中是否可以看到外部所看到的结果(参见清单4)。
清单4. 测试Pig
$ pig2011-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:80202011-12-10 06:39:44,988 [main] INFO  org.apache.pig.... connecting to map-reduce \job tracker at: 0.0.0.0:8021grunt> cd hdfs:///grunt> lshdfs://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. 获得一些测试数据
grunt> mkdir testgrunt> cd testgrunt> copyFromLocal /etc/passwd passwdgrunt> lshdfs://0.0.0.0/test/passwd<r 1> 1728
接下来,在 Hadoop文件系统中测试数据现在是安全的,您可以尝试另一个脚本。请注意,您可以在Pigcat文件,查看其内容(只是看看它是否存在)。在这个特殊示例中,将确定在passwd文件中为用户指定的外壳数量(在passwd文件中的最后一列)。
要开始执行该操作,需要从 HDFS将您的 passwd文件载入一个 Pig关系中。在使用 LOAD运算符之前就要完成该操作,但在这种情况下,您可能希望将密码文件的字段解析为多个独立的字段。在本例中,我们指定了PigStorage函数,您可以使用它来显示文件的分隔符(本例中,是冒号[:]字符)。您也可以用AS关键字指定独立字段(或架构),包括它们的独立类型(参见清单6)。
清单6.将文件读入一个关系中
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.将元组分组为其外壳的一个函数
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.利用每个外壳的计数对结果进行分组
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>
备注:如果要将该代码作为一个脚本来执行,只需将脚本输入到某个文件中,然后使用pigmyscript.pig来执行它。


诊断运算符

Pig支持大量诊断运算符,您可以用它们来调试Pig脚本。正如您在之前的脚本示例中所看到的,DUMP运算符是无价的,它不仅可以查看数据,还可以查看数据架构。您还可以使用DESCRIBE运算符来生成一个关系架构的详细格式(字段和类型)。
EXPLAIN运算符更复杂一些,但也很有用。对于某个给定的关系,您可以使用EXPLAIN来查看如何将物理运算符分组为MapReduce任务(也就是说,如何推导出数据)。
2PigLatin 中的诊断运算符及其描述提供了一个列表。
2. Pig Latin诊断运算符

运算符

描述

DESCRIBE

返回关系的架构。

DUMP

将关系的内容转储到屏幕。

EXPLAIN

显示 MapReduce执行计划。


用户定义的函数

虽 然 Pig在本文探讨的范围内是强大且有用的,但是通过用户定义的函数(UDF)可以使它变得更强大。Pig脚本可以使用您为解析输入数据、格式化输出数据甚至运算符等定义的函数。UDF是用Java语言编写的,允许Pig支持自定义处理。UDF是将Pig扩展到您的特定应用程序领域的一种方式。您可以在参考资料中了解有关UDF开发的更多信息。


Pig用户

正 如您从这篇短文中可以看到的,Pig是一个强大的工具,可以在Hadoop集群中查询数据。它是如此强大,Yahoo!估计,其Hadoop工作负载中有40%60%PigLatin 脚本产生。在Yahoo!100,000CPU中,大约有50%CPU仍在运行Hadoop
Yahoo!并不是利用Pig的惟一组织。您在Twitter中也会发现Pig(用于处理日志和挖掘微博数据);在AOLMapQuest上也会发现它(用于分析和批量数据处理);而在LinkedIn上,Pig用于发现您可能认识的人。据报道,Ebay使用Pig来实现搜索优化,而adyard的推荐工具系统有大约一半都使用了Pig
0 0
原创粉丝点击