代码改变世界

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种基本数据类型:intlongfloatdoublechararrybytearray,3种复核类型:MapTupleBag

   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 
View Code

   范例:A = load 'mydata' as (f1:chararray,f2:chararray)

      B = filter A by not f1 marches '.*pccpa.*'   --在A中查找并将f1不匹配"包含字符pccpa"的记录,并保存到B中

5、数据分组,关键字groupcogroup

   语法: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、数据连接,关键字joinleft joinright 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';