您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > [原创]Apache Pig的一些基础概念及用法总结(1)
[原创]ApachePig的一些基础概念及用法总结(1)转载必须注明出处:[]本文可以让刚接触pig的人对一些基础概念有个初步的了解。本文大概是互联网上第一篇公开发表的且涵盖大量实际例子的ApachePig中文教程(由Google搜索可知),文中的大量实例都是作者DarranZhang(website:codelast.com)在工作、学习中总结的经验或解决的问题,并且添加了较为详尽的说明及注解,此外,作者还在不断地添加本文的内容,希望能帮助一部分人。Apachepig[]是用来处理大规模数据的高级查询语言,配合Hadoop使用,可以在处理海量数据时达到事半功倍的效果,比使用Java,C++等语言编写大规模数据处理程序的难度要小N倍,实现同样的效果的代码量也小N倍。Twitter就大量使用pig来处理海量数据——有兴趣的,可以看Twitter工程师写的这个PPT[]。但是,刚接触pig时,可能会觉得里面的某些概念以及程序实现方法与想像中的很不一样,甚至有些莫名,所以,你需要仔细地研究一下基础概念,这样在写pig程序的时候,才不会觉得非常别扭。本文基于以下环境:pig0.8.1先给出两个链接:pig参考手册1[],pig参考手册2[]。本文的部分内容来自这两个手册,但涉及到翻译的部分,也是我自己翻译的,因此可能理解与英文有偏差,如果你觉得有疑义,可参考英文内容。【配置Pig语法高亮】在正式开始学习Pig之前,你首先要明白,配置好编辑器的Pig语法高亮是很有用的,它可以极大地提高你的工作效率。如果你在Windows下编写Pig代码,好像还真没有什么轻量级的编辑器插件(例如Notepad++的插件之类的)可以实现对.pig文件的语法高亮显示,我建议你使用Notepad++,在“UserDefineLanguage”中自定义Pig语法高亮方案(我这样做之后感觉效果很好);如果你觉得麻烦,那么你可以直接用Notepad++以SQL的语法高亮来查看Pig代码,这样的话可以高亮Pig中的一部分关键字。在Linux下,选择就很多了,大分部人使用的是vi,vim,但我是个Emacs控,所以我就先说说如何配置Emacs的Pig语法高亮。此插件是一个很好的选择:那么,怎么使用这个插件呢?下载piglatin.el文件,将它放置在任何地方——当然,为了方便,最好是放在你登录用户的根目录下(也就是与.emacs配置文件在同一目录下),然后将其重命名为“.piglatin.el”注意前面是有一个点的,也就是说将这个文件设置成隐藏文件,否则可能会误删了。然后,在.emacs文件中的最后,添加上如下一行:(load-file/home/abc/.piglatin.el)这里假设了你的.piglatin.el文件放置的位置是在/home/abc/目录下,也就是说emacs会加载这个文件,实现语法高亮显示。现在,你再打开一个.pig文件试试看?非常令人赏心悦目的高亮效果就出来了。效果如下图所示:其实Emacs也有Windows版的,如果你习惯在Windows下工作,完全可以在Windows下按上面的方法配置一下Pig语法高亮(但是Windows版的Emacs还需要一些额外的配置工作,例如修改注册表等,所以会比在Linux下使用要麻烦一些,具体请看这篇文章[=4802])。文章来源:[]下面开始学习Pig。(1)关系(relation)、包(bag)、元组(tuple)、字段(field)、数据(data)的关系编码无悔/Intent&Focused最优化之路页码,1/202012/10/30第1页/共20页一个关系(relation)是一个包(bag),更具体地说,是一个外部的包(outerbag)。•一个包(bag)是一个元组(tuple)的集合。在pig中表示数据时,用大括号{}括起来的东西表示一个包——无论是在教程中的实例演示,还是在pig交互模式下的输出,都遵循这样的约定,请牢记这一点,因为不理解的话就会对数据结构的掌握产生偏差。•一个元组(tuple)是若干字段(field)的一个有序集(orderedset)。在pig中表示数据时,用小括号()括起来的东西表示一个元组。•一个字段是一块数据(data)。•“元组”这个词很抽象,你可以把它想像成关系型数据库表中的一行,它含有一个或多个字段,其中,每一个字段可以是任何数据类型,并且可以有或者没有数据。“关系”可以比喻成关系型数据库的一张表,而上面说了,“元组”可以比喻成数据表中的一行,那么这里有人要问了,在关系型数据库中,同一张表中的每一行都有固定的字段数,pig中的“关系”与“元组”之间,是否也是这样的情况呢?不是的。“关系”并不要求每一个“元组”都含有相同数量的字段,并且也不会要求各“元组”中在相同位置处的字段具有相同的数据类型(太随意了,是吧?)文章来源:[](2)一个计算多维度组合下的平均值的实际例子为了帮助大家理解pig的一个基本的数据处理流程,我造了一些简单的数据来举个例子——假设有数据文件:a.txt(各数值之间是以tab分隔的):问题如下:怎样求出在第2、3、4列的所有组合的情况下,最后两列的平均值分别是多少?例如,第2、3、4列有一个组合为(1,2,3),即第一行和最后一行数据。对这个维度组合来说,最后两列的平均值分别为:(4.2+1.4)/2=2.8(9.8+0.2)/2=5.0而对于第2、3、4列的其他所有维度组合,都分别只有一行数据,因此最后两列的平均值其实就是它们自身。特别地,组合(7,9,9)有两行记录:第三、四行,但是第三行数据的最后两列没有值,因此它不应该被用于平均值的计算,也就是说,在计算平均值时,第三行是无效数据。所以(7,9,9)组合的最后两列的平均值为2.6和6.2。我们现在用pig来算一下,并且输出最终的结果。先进入本地调试模式(pig-xlocal),再依次输入如下pig代码:pig输出结果如下:这个结果对吗?手工算一下就知道是对的。文章来源:[]下面,我们依次来看看每一句pig代码分别得到了什么样的数据。①加载a.txt文件,并指定每一列的数据类型分别为chararray(字符串),int,int,int,double,double。同时,我们还给予了每一列别名,分别为col1,col2,……,col6。这个别名在后面的数据处理中会用到——如果你不指定别名,那么在后面的处理中,就只能使用索引($0,$1,……)来标识相应的列了,这样可读性会变差,因此,在列固定的情况下,还是指定别名的好。将数据加载之后,保存到变量A中,A的数据结构如下:可见,A是用大括号括起来的东西。根据本文前面的说法,A是一个包(bag)。这个时候,A与你想像中的样子应该是一致的,也就是与前面打印出来的a.txt文件的内容是一样的,还是一行一行的类似于“二维表”的数据。文章来源:[]②按照A的第2、3、4列,对A进行分组。pig会找出所有第2、3、4列的组合,并按照升序进行排列,然后将它们与对应的包A整合起来,得到如下的数据结构:可见,A的第2、3、4列的组合被pig赋予了一个别名:group,这很形象。同时我们也观察到,B的每一行其实就是由一个group和若干个A组成的——注意,是若干个A。这里之所以只显示了一个A,是因为这里表示的是数据结构,而不表示具体数据有多少组。实际的数据为:1234567[root@localhostpig]$cata.txta1234.29.8a3053.52.1b799--a7992.66.2a1257.75.9a1231.40.21234A=LOAD'a.txt'AS(col1:chararray,col2:int,col3:int,col4:int,col5:double,col6:double);B=GROUPABY(col2,col3,col4);C=FOREACHBGENERATEgroup,AVG(A.col5),AVG(A.col6);DUMPC;1234((1,2,3),2.8,5.0)((1,2,5),7.7,5.9)((3,0,5),3.5,2.1)((7,9,9),2.6,6.2)1A:{col1:chararray,col2:int,col3:int,col4:int,col5:double,col6:double}1B:{group:(col2:int,col3:int,col4:int),A:{col1:chararray,col2:int,col3:int,col4:int,col5:double,col6:double}}1234((1,2,3),{(a,1,2,3,4.2,9.8),(a,1,2,3,1.4,0.2)})((1,2,5),{(a,1,2,5,7.7,5.9)})((3,0,5),{(a,3,0,5,3.5,2.1)})((7,9,9),{(b,7,9,9,,),(a,7,9,9,2.6,6.2)})页码,2/202012/10/30第2页/共20页可见,与前面所说的一样,组合(1,2,3)对应了两行数据,组合(7,9,9)也对应了两行数据。这个时候,B的结构就不那么明朗了,可能与你想像中有一点不一样了。文章来源:[]③计算每一种组合下的最后两列的平均值。根据上面得到的B的数据,你可以把B想像成一行一行的数据(只不过这些行不是对称的),FOREACH的作用是对B的每一行数据进行遍历,然后进行计算。GENERATE可以理解为要生成什么样的数据,这里的group就是上一步操作中B的第一项数据(即pig为A的第2、3、4列的组合赋予的别名),所以它告诉了我们:在数据集C的每一行里,第一项就是B中的group——类似于(1,2,5)这样的东西)。而AVG(A.col5)这样的计算,则是调用了pig的一个求平均值的函数AVG,用于对A的名为col5的列求平均值。前文说了,在加载数据到A的时候,我们已经给每一列起了个别名,col5就是倒数第二列。到这里,可能有人要迷糊了:难道AVG(A.col5)不是表示对A的col5这一列求平均值吗?也就是说,在遍历B(FOREACHB)的每一行时候,计算结果都是相同的啊!事实上并不是这样。我们遍历的是B,我们需要注意到,B的数据结构中,每一行数据里,一个group对应的是若干个A,因此,这里的A.col5,指的是B的每一行中的A,而不是包含全部数据的那个A。拿B的第一行来举例:((1,2,3),{(a,1,2,3,4.2,9.8),(a,1,2,3,1.4,0.2)})遍历到B的这一行时,要计算AVG(A.col5),pig会找到 (a,1,2,
本文标题:[原创]Apache Pig的一些基础概念及用法总结(1)
链接地址:https://www.777doc.com/doc-5105931 .html