实验目的
了解pig的该概念和原理
了解pig的思想和用途
了解pig与hadoop的关系
实验原理
1.Pig
相比Java的MapReduce API,Pig为大型数据集的处理提供了更高层次的抽象,与MapReduce相比,Pig提供了更丰富的数据结构,一般都是多值和嵌套的数据结构。Pig还提供了一套更强大的数据变换操作,包括在MapReduce中被忽视的连接Join操作。
Pig包括两部分:
用于描述数据流的语言,称为Pig Latin。
用于执行Pig Latin程序的执行环境,当前有两个环境:单JVM中的本地执行环境和Hadoop集群上的分布式执行环境。
Pig内部,每个操作或变换是对输入进行数据处理,然后产生输出结果,这些变换操作被转换成一系列MapReduce作业,Pig让程序员不需要知道这些转换具体是如何进行的,这样工程师可以将精力集中在数据上,而非执行的细节上。
Pig提供了一种基于Hadoop的并行地执行数据流处理的引擎。它包含了一种脚本语言,称为Pig Latin,用来描述这些数据流。Pig Latin本身提供了许多传统的数据操作(如join,sort,filter等),同时允许用户自己开发一些自定义函数用来读取、处理和写数据。
Pig是一个Apache开源项目。这意味着用户可以免费下载源码或者二进制包,自由使用它,对这个项目贡献自己的代码,同时也可以在Apache License的许可范围下将Pig 用到自己产品中或者在需要的时候修改代码来满足特定需求。
2.Pig与hadoop
Pig运行于hadoop之上,它同时使用到hadoop分布式文件系统HDFS和hadoop处理系统MapReduce。
HDFS是一个分布式文件系统,它将文件存储到hadoop集群的各个节点上。它负责将文件分割成许多数据块然后分发到不同的节点机器上,其中包括对每个数据块进行多份冗余备份,这样可以避免因为某台机器宕掉而造成数据丢失。HDFS提供一种类似POSIX的用户交互形式给用户 。默认情况下,Pig从HDFS中读取输入文件,使用HDFS来存放Mapreduce任务所生成的中间数据,最终将输出写入HDFS中。
Mapreduce是一个简单而强大的并行数据处理算法。MapReduce计算框架的每个任务都由3个主要阶段组成:map阶段、shuffle阶段和reduce阶段。在map阶段,程序可以并行独立操作输入数据中的每一条记录。因为可以同时运行多个map任务,所以即使输入的数据量达到GB或者TB级别,只要有足够多的机器,map阶段通常在一分钟内就可以完成。
MapReduce任务的一个特别之处在于需要确定数据是根据哪个键进行收集的。例如,假设用户在处理一个网站的Web服务器日志,而且这个网站需要用户登录后才能操作,那么用户就可能会使用用户ID作为数据收集的键,因为通过这个用户ID作为数据收集的键,因为通过这个用户ID就可以知道每个用户在这个网站上的对应所有操作。map阶段后紧跟着就是shuffle阶段,在这个阶段数据已经根据用户指定的键收集起来并且分发到不同的机器上去了,这是为reduce阶段做准备,包含同一键的所有记录将会交由同一个reduce处理。
在reduce阶段,程序将提取每个键以及包含该键的所有记录。这个过程也是在多台机器上并行执行完成的。当处理完所有组时,reduce就可以写输出了。
实验环境
1.操作系统
服务器:Linux_Centos
操作机:Windows_7
服务器默认用户名:root,密码:123456
操作机默认用户名:hongya,密码:123456
步骤1:认识Pig
1.1Pig Latin,一种并行数据流语言。Pig Latin语言与传统的关系数据库中的数据库操作语言非常类似。但是Pig Latin语言更侧重于对数据的查询和分析,而不是对数据进行修改和删除等的操作。另外,由于PigLatin可以在Hadoop的分布式的云平台上运行,它的这个特点可以让其具有其它数据库无法比拟的速度优势,能够在短时间内处理海量的数据。例如,处理系统日志文件、处理大型数据库文件、处理特定Web数据等。
除此之外,我们在使用Pig Latin语言编写程序的时候,不必关心如何让程序能够更好的在Hadoop平台上运行,因为这些任务都是由Pig系统自行分配的,不需要程序员参与。因此,程序员只需要专注于程序的编写,这样大大减轻了程序员的负担。
Pig Latin是这样的一个操作:通过对关系进行处理产生另外一组关系。Pig Latin语言在书写一条语句的时候能够跨越多行,但是必须以半角的分号来结束。
Pig Latin语言通常按照下面的流程来编写:
通过一条LOAD语句从文件系统中读取数据;
通过一系列转换语句对数据进行处理;
通过一条STORE语句把处理结果输出到文件系统中,或者使用一条DUMP语句把处理结果输出在屏幕上。
LOAD和STORE语句有严格的语法规定,用户很容易就能掌握,关键是如何灵活的使用转换语句对数据进行处理。
1.2查询语言和数据流语言的比较
大体一瞥,人们会说Pig Latin不过是SQL的一个面向过程化的版本。尽管确实有一定的相似性,但其实两者具有非常多的差异。SQL是一种查询语言,它关注与允许用户构造查询,它允许用户去描述他们想得到什么问题的答案,而不是如何给出问题的答案。然而Pig Latin中,用户可以详细描述如何对输入的数据进行处理。
Pig Latin和SQL的另一个主要区别是SQL面向的是回答一个问题,因此当用户想同时进行多个数据操作时,他们要么使用多个查询语句,这时需要将一些查询的中间数据存放到临时表中;要么写一个大的包含子查询的查询语句,将一些初始的处理过程由子查询来完成。然而,很多用户发现子查询令人困惑而且也并非那么容易去构建。同时,子查询使用的是由内而外的设计,也就是说,在数据管道最里面的子查询会最先执行。
Pig被设计为实现知道将要进行的一系列的数据操作,因此不需要通过颠倒顺序的子查询的方式来写数据管道,也无需使用临时表来存放中间数据。这点将通过例子1-1和例子1-2来进行演示。
现在假设有个用户想先按某个键对表进行group分组操作,然后和第二张表进行join操作。在SQL查询中,因为join操作发生在group操作之后,要么使用子查询,要么写两个查询语句,同时将中间结果保存到临时表中。例子1-2用到一个临时表,因为这样可读性要好些。
例1-1 SQL中先进行分组然后进行连接操作
CREATE TEMP TABLE t1 AS
SELECT customer, sum(purchase) AS total_purchases
FROM transactions
GROUP BY customer
SELECT customer, total_purchases,zipcode
FROM t1,customer_profile
WHERE t1.customer = customer_profile.customer;
在Pig Latin中,是另外一种方式,如例1-2所示。
例1-2 Pig Latin中先进行分组然后进行连接操作
--加载汇报文件,按照customer字段进行分组,然后计算他们的总购物金额
txns = load 'transactions' as (customer, purchase);
grouped = group txns by customer;
total = foreach grouped generate group, SUM(txns.purchase) as tp;
--加载customeer_profile文件
profile = load 'customer_profile' as (customer, zipcode);
--对已经分好组并进行了累加计算的汇报文件数据和customer_profile文件进行连接
answer = join total by group, profile by customer;
--将结果输出到控制台
dump answer;
此外,SQL和Pig Latin各因不同的应用场景而生。SQL的应用场景是RDBMS,在这种场景下,数据是标准化的,并且加上了模式和其他的一些特有的约束(例如,null值也是不可以脱离约束单独存在的等)。Pig是为Hadoop数据处理环境而设计的,在这种环境下,模式有时是未知的或不一致的,数据可能没有进行恰当的约束而且很少进行数据标准化。基于这些不同,Pig不需要将数据事先导入表中,当数据导入HDFS中后,它就可以直接操作这些存放在HDFS中的数据。
步骤2:Pig和MapReduce的区别
Pig比直接使用Mapreduce有以下几个优势:
Pig Latin提供了所有标准的数据处理操作,例如join、filter、group by、order by、union等。MapReduce直接提供了group by操作(也就是shuffle和reduce两个阶段做好的事情),同时通过实现分组操作简介地提供了order by操作。过滤操作和推测执行操作可以在map阶段进行简单实现。但是其他的操作,特别是join操作无法提供,所以必须由用户自己进行代码实现。
Pig提供了一些对这些标准的数据操作的复杂的、完备的实现。例如,因为每个键对应的记录的个数是很少是均匀分布在集群中的,所以提交给reduce的数据经常会产生数据倾斜。也就是说,有的reduce需要比别的reduce处理10倍或更多的数据。Pig具有join和order by 操作可以处理这种情况,而且(在一些情况下)可以重新均衡reduce负荷。这些需要Pig团队花费好几个月的时间编写MapReduce程序,然后再重构代码,这些确实耗费时间。
在MapReduce中,在map阶段和reduce阶段的内部的数据处理对于系统来说是不透明的。这意味着MapReduce没有机会优化或者检查用户的代码。Pig另一方面,可以通过分析Pig Latin脚本来了解用户描述的数据流。这意味着Pig可以在早期进行错误检查(例如用户是否将一个string类型的字段放到一个integer类型的字段中?)和进行优化(例如这两个group操作是否可以合并?)
MapReduce没有一个类型系统,这是有意这么设计的,因为这样可以给用户更大的自由度去使用他们自己的数据类型和序列化框架。但这样就产生了一个不好的问题,就是限制了系统在运行前和运行时对用户代码进行检查的能力。
这几个方面都表明Pig Latin相对于MapReduce Java代码更容易编写和维护。当然Pig所带来的的这些便利同样是有代价的。通过MapReduce框架可以开发一些算法,在Pig中却很实现。同时对于开发者,他们需要放弃一个层次的控制权。一个优秀的工程师,只要给予足够的时间,总是可以将普通的系统做的足够好。因此,对于不常见的算法或者是对于性能要求很高的话,这种情况下使用MapReduce仍然是正确的选择。基本上这种情况也和选择Java编码而不选择使用像Python这样的脚本语言的情形是一样的。Java功能强大,但是因为它是高级程序语言,所以使用它开发需要比脚本语言花费更多的时间。开发者根据实际情况选择合适的工具。
步骤3:Pig的用途
Pig Latin的使用场景可以分为独立的三大类;传统的抽取转换加在(ETL)数据流、原生数据研究和迭代处理。
最大的使用场景就是数据流了。一个通常的例子就是网络公司从他们的Web服务器上收集到日志,进行数据清洗,之后进行简单的聚合预计算,然后倒入数据仓库中。在这种情况下,数据被加载到计算网格中,之后使用Pig从数据泥潭中清理出有价值的数据。同时还可以使用Pig将用户网页操作数据和用户数据库进行join连接,这样可以将用户cookie和已知的用户信息关联起来。
另外一个数据流应用例子是使用Pig离线数据来建立用户行为预测模型。pig被用来扫描所有用户和网站的交换数据,最终将用户分为各种各样的群组。然后对于每个群组会生成一个数据模型,根据该模型可以预知这个群组的用户对各种类型的广告或者新闻文章的反应是什么样子的。通过这种方式,网站可以知道展示什么样的广告可以更有可能获得更多的点击,或者发布什么样的新闻故事可以更有可能吸引用户和挽留客户再次访问。
传统上,使像SQL这样的语言执行点对点的查询可以快速地为问题准备好相应的数据。然而,对于原始数据的研究,一些用户还是偏向使用Pig Latin脚本。因为Pig可以在无模式,信息不全,或者模式不一致的情况下进行操作,同时因为Pig可以很容易地控制封装的数据,因此对于那些期望在数据没有进行清洗也没有写入数据仓库的情况下,分析数据的研究人员经常更偏好于使用Pig。经常处理大规模数据集的研究人员会使用像Perl或者Python这样的脚本语言进行处理。具有这些使用背景的用户通常更加喜欢使用Pig这样的数据流范式而非像SQL那样的声明式查询语言。
创建迭代处理用户模型的用户也开始使用Pig。假设有一个新闻门户网站,它保留了一个它跟踪的关于该网站的所有新闻故事的图。在这个图中,每个新闻故事都是一个节点,节点间的连线表示的是相关故事间的关系。例如,所有关于即将来临的选举的故事都是联系到一起的。每五分钟都有一组新的故事进来,这时数据处理引擎需要将这组故事增加到图中。这些故事中有一些是新的,有一些是对之前故事进行的更新,还有一些是替代之前已经存储的一些故事的。这时需要对整个故事图做一些数据处理步骤。例如,对于建立行为目的模型的处理过程就需要将用户数据和整个故事进行连接。每五分钟重新运行整个图是不可行的,因为对于适当数量的硬件资源来说在五分钟内运行出结果是不可能的。但是模型创建者不想只是每天更新一次这些模型,因为那意味着会错过一整天的时间来提供机会。
为了应付这个问题,有必要定期地首先对整个图进行连接,例如可以按照天来进行连接。然而,每五分钟一旦有数据进来,就可以立即完成对新进来的数据进行连接操作,同时这个结果可以对整个图做连接的结果整合在一起的,这个组合步骤并不容易,因为需要在五分钟内完成对整个图进行插入、更新和删除操作。使用Pig Latin来表达这种组合关系是可以的并且是相当方便的。
目前所说的一切都隐含着一点:Pig(与MapReduce一样)是面向数据批处理的。如果需要处理的是GB或者TB数量级的数据,那么Pig是个不错的选择。但是因为它期望的是序列地读取一个文件中的所有记录然后序列地将输出写入存储中,因此对于那些需要写单条或者少量记录,或者查询随机序列下的多条不同记录这样的任务,Pig(与MapReduce一样)并非是个好选择。
步骤4:Pig的设计思想
在早期,作为潜在贡献者加入Pig项目的人们并非了解这个项目究竟是关于什么的。他们并不清楚怎样做才是最好的贡献或者哪些贡献会被接受以及哪些不会被接受。因此,Pig团队发布了一个项目设计思想声明,其内容总结为Pig渴望成为:
4.1Pig什么都吃
不管数据是否有元数据,Pig都可以操作。不管数据是关系型的、嵌套型的,或者是非结构化的,Pig也同样可以操作。而且它还可以很容易地通过扩展,不单单可以操作文件,还可以操作key/value型的存储,以及数据库等。
4.2Pig无处不在
Pig期望成为一种并行数据处理语言。它不会局限于一种特殊的并行处理框架。它首先是基于Hadoop之上的实现,但是我们期望它并非只能在Hadoop平台上使用。
4.3Pig是家畜
Pig被设计为可以让用户很容易控制和修改的语言。
Pig允许用户随时整合加入他们的代码,因此目前它支持用户自定义字段类型转换函数、用户自定义聚合方法函数和用户定义条件式函数。这些函数可以使用Java来写也可以使用最终可以编译成Java代码的脚本语言(例如Jython)编写。Pig支持用户定义的加载和存储函数。Pig通过自己的stream命令和需要MapReduce相关的JAR包的mapreduce命令可以执行外部的执行命令。Pig同样允许用户为自己的特定使用场景提供一个用户自定义的分区方法函数,使他们执行任务在reduce阶段可以达到一个均衡的负荷。
Pig有一个优化器,它可以将Pig Latin脚本中的操作过程进行重新排列以达到更好的性能,例如将MapReduce任务进行合并等。但是,如果对于某种情形下这种优化是不必要的话,用户可以很容易地将最优控制器关闭,这样执行过程就不会发生改变。
4.4Pig会飞
Pig处理数据很快。我们将会持续化的优化性能,同时不会增加一些使Pig显得较重而降低性能的新功能。
步骤5:关于Pig其他
5.1Pig的发展史
Pig最初是作为Yahoo的一个探索性的项目,Yahoo的科学家们设计了Pig并且给出了一个原型实现。正如2008年发表在数据管理专业委员会(SIGMOD)杂志的一篇论文所描述的,研究者认为Hadoop所描述的MapReduce框架“过于底层和严格,需要用户话费大量时间编写代码,而且很难维护和重用。”同时他们注意到MapReduce用户对像SQL这样的声明语言并不熟悉。因此他们着手开发“一种叫做Pig Latin的新语言,这种语言被设计为在像SQL这样的声明式类型的语言和像MapReduce这种较底层的过程式语言之间达到一个非常好的平衡点。”
最初Yahoo的Hadoop使用者开始采用Pig。之后一个开发工程师团队开始接手Pig的最初原型并将Pig原型开发成一个达标产品级别的可用产品。在这个时间点左右,也就是2007年的秋天,Pig通过Apache孵化器进行开源。一年后也就是2008年的9月,Pig的第一的发布版本出现了。同年的晚些时候,Pig从孵化器中毕业,这个是提升为Apache Hadoop项目的一个子项目。
2009年早期其他公司在他们的数据处理中开始使用Pig。Amazon也将它的弹性MapReduce服务中的一部分。2009年末,Yahoo公司所运行的Hadoop任务有一半是Pig任务。在2010年,Pig发展持续增长,这一年Pig从Hadoop的子项目中脱离出来,自己成为了一个最高级别的Apache项目。
5.2Pig和数据库的区别
Pig Latin是面向数据流的编程方式,而SQL是一种描述型编程语言。我们以前学习SQL的时候经常听到过这样一句话:用SQL,你只需要告诉它你需要什么,具体怎么做交给SQL就行了。而Pig Latin是需要你一步一步根据数据流的处理方式来编程的,也就是说你要设计数据流的每一个步骤,有点类似SQL的查询规划器。
传统的关系数据库(RDBMS)需要你预先定义表结构(模式),所有的数据处理都是基于这些有着严格格式的表数据。而Pig则不需要这样,你可以在运行时动态定义模式。本质上来说,Pig可以处理任何格式的元组。一般情况下,Pig的数据来源是文件系统,比如HDFS,而RDBMS的数据是存储在数据库中 的。(备注:关于元组的概念,基本和Python中的touple是差不多的)
Pig支持比较复杂的,比如嵌套结构的数据处理。这种特殊的处理能力加上UDF(用户自定义函数)使得Pig具有更好的可定制型。
一些RDBMS特有的特性是Pig所没有的,比如事务处理和索引。Pig和MapReduce一样,是基于批量的流式写操作。
5.3Pig和Hive
Hive和Pig是hadoop之上的两个数据查询和处理的工具。Hive的语法与SQL很像。Pig是一种处理数据的脚本语言。如果不用Hive和 Pig之类的工具,而是用Hodoop上的原生态的Java的来查数据的话,开发效率比较低。一个简单的sql需要写一页代码。
Pig是一种编程语言,它简化了Hadoop常见的工作任务。Pig可加载数据、表达转换数据以及存储最终结果。Pig内置的操作使得半结构化数据变得有意义(如日志文件)。同时Pig可扩展使用Java中添加的自定义数据类型并支持数据转换。
HIVE介于Pig和传统的RDBMS之间,和Pig一样,Hive也被设计为HDFS作为存储,但是他们之间有着显著的区别。Hive的查询语言HiveQL,是基于SQL的。任何熟悉SQL的人都可以轻松使用HiveQL写查询。和RDBMS相同。Hive要求所有数据必须存储在表中,表必须有模式,而模式由Hive进行管理。但是Hive允许为预先存在于HDFS的数据关联一个模式。所以,数据的加载步骤是可选的。
和Pig一样,Hive也不支持低时延查询。