Pig -- 基于Hadoop的轻量级大规模数据分析工具
2014-12-10 10:00 hduhans 阅读(1800) 评论(0) 收藏 举报Pig是Apache项目的一个子项目,提供了一个支持大规模数据分析的平台。基于Hadoop的大规模数据分析工具,它提供的SQL-LIKE语言叫Pig Latin,该语言的编译器会把类SQL的数据分析请求转换为一系列经过优化处理的MapReduce运算。Pig是一种描述性编程语言,比Hive轻量,可以直接使用而不需要写大量的MapReduce Java代码,在实际的大数据环境中经常被使用。
一、Pig基础知识
1、基本概念
Pig是一种描述性编程语言,我们可以通过他提供的语句来实现简单的HDFS数据处理与统计,他会自动转化成优化后的MapReduce程序并执行。也就是说,Pig最大的作用就是对mapreduce算法实现了一套shell脚本,类似我们通常熟悉的SQL语句,在Pig中称之为Pig Latin,在这套脚本中我们可以对加载出来的数据进行排序、过滤、求和、分组(group by)、关联(Joining),Pig也可以由用户自定义一些函数对数据集(UDF,user-defined functions)进行操作。
2、主要特点
1)易于编程。可以很简单地使用pig来实现高度并行的数据分析任务。
2)自动优化。编写pig任务运行时,pig会自动转化成MapReduce程序执行并优化。
3)可扩展性。用户可以编写自己的函数来进行特殊用途的处理。
3、数据类型
Pig有6种基本数据类型:int、long、float、double、chararry、bytearray,3种复核类型:Map、Tuple、Bag。
Tuple类型如:(12.5,hello world,-2),Bag类型如:{(12.5,hello world,-2),(2.87,bye world,10)},Map类型如:{key#value}。
4、Pig与Hive的区别
Pig与Hive都是Hadoop的子项目,他们的作用类似,都是用来简化大数据的处理的工具。Pig是看做是一个MapReduce实现的脚本工具,而Hive则扮演者数据仓库的角色。
Pig是一种编程语言,使用了一种面向数据流的编程语言-Pig Latin语言,一步步执行输入操作,每一步都是数据的一个简单变换。Pig可加载数据、表达转换数据以及存储最终结果。Pig内置的操作使得半结构化数据变得有意义(如日志文件)。同时Pig可扩展使用Java中添加的自定义数据类型并支持数据转换。
HIVE介于Pig和传统的RDBMS之间,在Hadoop中扮演数据仓库的角色。Hive使用了HiveQL查询语言,是基于SQL的,因此任何熟悉SQL的程序员都可以很轻松的使用HiveQL进行查询。
有关于Pig Latin语言和SQL语言的区别,有一个形象的比喻:用SQL,你只需要告诉它你需要什么,具体怎么做交给SQL就行了。而Pig Latin是需要你一步一步根据数据流的处理方式来编程的,也就是说你要设计数据流的每一个步骤,有点类似SQL的查询规划器。
其他使用上的区别如图1-1所示:

图1-1 Pig与Hive在使用上的区别
二、Pig安装
Pig只需安装在一台机子上,通常安装与主节点,本实例安装版本:pig-0.11.1.tar.gz。
1、将pig安装包解压到/usr/local目录下,并重命名为pig。
2、配置环境变量,执行命令:vi /etc/profile,增加export $PIG_HOME=/usr/local/bin,并在export PATH中增加$PIG_HOME/bin,然后执行命令:source /etc/profile使配置文件立即生效。
3、配置Pig环境,执行命令:vi /usr/local/pig/conf/pig.properties,增加如下两行内容:
fs.default.name=hdfs://hadoop0:9000 mapred.job.tracker=hadoop0:9001
三、Pig运行模式与方式
Pig有两种运行模式:Local模式和MapReduce模式,每种模式分别有三种运行方式:Grunt Shell方式、脚本文件方式和嵌入式程序方式。
1、Local模式
1)Grunt Shell方式
进入命令:pig -x local,如果直接输入命令:pig,则Pig将根据是否设置MapReduce环境变量自动选择Local模式或MapReduce模式。
当前模式与Window的Dos窗口很类似,逐条执行键入的命令。
2)脚本文件方式
执行脚本文件命令:pig -x local script.pig,可以批量的执行pig命令。
3)嵌入式程序方式
将pig命令嵌入到Java语言中,然后执行对应的java文件。利用pig编译java文件命令:javac -cp pig-*.*.*-core.jar local.java,执行编译后的class文件命令:javac -cp pig-*.*.*-core.jar:. local。
2、MapReduce模式
1)Grunt Shell方式
进入命令:pig -x mapreduce。
2)脚本文件方式
执行脚本文件命令:pig -x mapreduce script.pig,可以批量的执行pig命令。
3)嵌入式程序方式
与Local模式下的嵌入式程序方式用法一致。
四、Pig Latin语言
Pig Latin是Pig使用的语言,与传统的关系数据库中的操作非常相似,但是更侧重于查询与分析。使用Pig Latin语言,程序员不需要关心运行效率,系统会自动以最优化的方式运行。
Pig Latin关键词不区分大小写,但变量名和udf区分大小写。单行注释用“--”,多行注释用“/*...*/”。
通常Pig Latin编写流程为:①通过LOAD语句从文件系统中读取数据;②通过一系列“转换”语句对数据进行处理;③通过STORE语句把处理结果存储到文件系统中,或通过DUMP语句将结果输出到屏幕上。
1、读取数据,关键字load
语法:load 'data' [using 函数] [as 字段类型]
范例:load 'myfile.txt' using PigStorage(',') as (f1:int,f2:int,d3:int) --加载hdfs文件myfile.txt,并使用分隔符,(默认为tab即\t)将内容按列划分提取为f1、f2和f3。注意只能使用一个字符作为分隔符进行划分。
2、数据存储,关键字store
语法:store 变量 into hdfs路径 [using 函数]
范例:store A into '/data/file' --将pig临时变量A对应的数据内容保存到HDFS文件/data/file中
store A into '/data/file' using PigStorage(',') --同上,但是保存数据时使用,作为分隔符,默认为tab(\t)分隔符
3、数据转换,关键字foreach
语法:foreach ... generate [*] [begin .. end]
范例:A = load 'mydata' as (f1,f2,f3,f4,f5,f6)
B = foreach A generate ..f3 --抽取A中的列f1、f2、f3作为B
C = foreach A generate f3..f5 --抽取A中的列f3、f4、f5作为C
D = foreach A genarate f5.. --抽取A中的列f5、f6作为D
一般foeach中重新生成的数据列名与原来保持一致,但是在generate中如果存在表达式,则必须给表达式列指定列明
A = load 'mydata' as (f1:chararray,f2:float)
B = foreach A generate f2 * 100.0 as f2,f2 * 100.0 --将A中的列f2*100.0作为B,此时B中有两列,第一列为f2,第二列无列名
4、数据过滤,关键字filter
语法:filter 变量 by [not] 列名 matches '正则表达式'
其中pig的正则表达式与java的正则表达式一致,在正则表达式中,各特殊字符的转义字符对应如下(使用方式:\\跟转义码):
点的转义:. ==> u002E
美元符号的转义:$ ==> u0024
乘方符号的转义:^ ==> u005E
左大括号的转义:{ ==> u007B
左方括号的转义:[ ==> u005B
左圆括号的转义:( ==> u0028
竖线的转义:| ==> u007C
右圆括号的转义:) ==> u0029
星号的转义:* ==> u002A
加号的转义:+ ==> u002B
问号的转义:? ==> u003F
反斜杠的转义: ==> u005C
范例:A = load 'mydata' as (f1:chararray,f2:chararray)
B = filter A by not f1 marches '.*pccpa.*' --在A中查找并将f1不匹配"包含字符pccpa"的记录,并保存到B中
5、数据分组,关键字group、cogroup
语法:group 变量 by 列名 --根据列名将变量对应的数据进行分组
group 变量 by (列名1,列名2) --根据列名1和列名2将变量对应的数据进行分组
group 变量 all --根据变量包含的所有字段将数据进行分组,注意group_all没有by
cogroup 变量1 by 列名1, 变量2 by 列名2 --将变量1和变量2根据相同类型的列名1和列名2进行分组并合并
可以用()同时对多个变量进行group,group之后变量分为两个部分,第一部分变量名是group(固定),第二部分变量是和原始bag一样的bag。
范例:A = load 'mydata' as (f1,f2,f3)
B = group A by (f1,f2) --根据列f1、f2将A的数据进行分组并保存至B中
describe B --此时B的格式为B:{group:{f1:bytearray,f2:bytearray},A:{f1:bytearray,f2:bytearray,f3:bytearray}}
C = load 'data1' as (id:int,val1:float)
D = load 'data2' as (id:int,val2:int)
E = cogroup C by id, D by id --通过C的id和D的id进行分组并将数据合并作为E
describe E --此时E的格式为E:{group: int,A: {id: int,val1: float},B: {id: int,val2: int}}
6、数据排序,关键字order by
语法:order 变量 by 列名1 [desc] [,字段2...]
范例:A = load 'mydata' as (f1,f2,f3)
B = order A by f1 --根据f1升序将A数据进行排序并保存至B中
C = order A by f1 desc,f2 --根据f1降序、f2升序将A数据进行排序并保存至C中
7、数据去重,关键字distinct
语法:distinct 变量
范例:A = load 'mydata' as (f1,f2)
B = distinct A --将A中f1、f2列同时相同的重复数据去除并保存至B中
注意:distinct只能去掉整个元组的重复行,不能去掉某几个特定列的重复行。
8、数据连接,关键字join、left join、right join
语法:join 变量1 by 字段1, 变量2 by 列名2 [,变量3 by 列名3...] --将多个变量根据列名1=列名2=列名3...进行连接查询
join 变量1 by (列名1,列名2), 变量2 by (列名3,列名4) --将变量1和变量2根据列名1=列名3并且列名2=列名4进行连接查询
join 变量1 by 列名1 left outer, 变量2 by 列名2 --根据变量1进行左连接查询,连接变量2,连接条件列名1=列名2
范例:A = load 'mydata1' as (fa1,fa2,fa3)
B = load 'mydata2' as (fb1,fb2,fb3)
C = join A by fa1, B by fb2 --根据列名fa1=fb1将A和B进行连接查询
D = join A by (fa1,fa2), B by (fb1,fb2) --根据列名fa1=fb1且fa2=fb2将A和B进行连接查询
E = join A by fa1 left outer,B by fb1 --根据列名fa1=fb1将A与B进行左连接查询
9、数据合并,关键字union
语法:union 变量1, 变量2 --将具有相同列名的两个变量数据进行合并
union onschema 变量1, 变量2 --将具有不同列名的两个变量数据进行合并,合并后的列为变量1和变量2的列名之和
范例:A = load 'mydata1' as (f1:int, f2:double)
B = load 'mydata2' as (f1:double, f2:float)
C = union A, B --将A和B数据进行合并操作,合并后数据列1类型为double,列2类型为double
D = load 'mydata3' as (fd1,f2,f3)
E = load 'mydata4' as (f2,f3,fd4)
F = union onschema D, E --将具有不同列的D和E数据进行合并,合并后列为(fd1,f2,f3,fd4)
注意:union 相当与sql中的union,但与sql不通的是pig中的union可以针对两个不同模式的变量:如果两个变量模式相同,那么union后的变量模式与变量的模式一样;如果一个变量的模式可以由另一各变量的模式强制类型转换,那么union后的变量模式与转换后的变量模式相同;否则,union后的变量没有模式。
10、其他常用语句
limit A 10 --取A中的前10条数据
sample A 0.2 --取A中的前20%数据
group A by f1 parallel 10 --设置reduce进程个数为10
describe A --显示A的schema模式
illustrate A --逐步显示数据A是如何被转换的
参考:http://www.cnblogs.com/siwei1988/archive/2012/08/06/2624912.html
五、利用pig处理手机流量数据统计分析
手机流量数据统计分析案例请参照《Hadoop学习(4)-- MapReduce》,此例使用pig来处理此案例,达到与MapReduce一样的处理效果。
1、将流量数据文件wlan上传到HDFS文件系统中,命令:hadoop fs -put /root/Download/wlan /wlan;
2、把HDFS中的数据转换为pig可以处理的模式,命令:A = LOAD '/input' AS (t0:long, msisdn:chararray, t2:chararray, t3:long, t4:long, t5:long, t6:long); 查看命令:DUMP A;
3、抽取需要处理的字段,命令:B = FOREACH A GENERATE msisdn, t6, t7, t8, t9;
4、对数据进行分组,命令:C = GROUP B BY msisdn;
5、对不同组的数据进行流量汇总统计,命令:D = FOREACH C GENERATE group, SUM(B.t6), SUM(B.t7), SUM(B.t8), SUM(B.t9);
6、将处理后的数据存储到HDFS中,命令:STORE D INTO '/wlan_result';
浙公网安备 33010602011771号