现在的位置: 首页 > 综合 > 正文

Hortonworks member of technical staff戴建勇解读Apache Pig的性能优化

2018年04月08日 ⁄ 综合 ⁄ 共 5116字 ⁄ 字号 评论关闭

以下为现场实录:

什么是Apache  Pig?ApachePig包括两个部分,首先是PigLatin的语言,是类SQL的数据处理语言。其次,Apache  Pig是在Hadoop这个软件上运行Pig  Latin语言的执行引擎,一部分是语言的部分,还有一部分是实践的部分。

比较一下Pig和Hadoop,跟Hadoop相比Pig具有更快的开发效率,所以可以用更少的代码实现和MapReduce同样的功能,而且Pig对常用的Hadoop进行了充分的优化,所以我们不需要重新写MapReduce,如果用Pig这些都已经是现成的了。

Pig和hive是解决同样的问题的,但和Hive相比Pig还是有显著的不同点,首先Pig是一个过程化的语言,它是一步一步的,基于过程化的语言,Hive说的是SQL的语言,这是描述性的语言。很多的开发人员更愿意使用过程化进行数据开发。对比HivePig还有一个显著的特点是具有灵活性,因为在Pig里面Schema不是必需的 。 Pig具有可扩充性,Pig约有所有的函数库,是可以扩充的,如果有用户觉得有一个好的函数,可以加入到Pig语言程序来,其他用户也可以使用你提供的函数。Pig是没有标准的,如果用Pig未必要拘泥于SQL的标准。

Pig用户和社区

雅虎90%的MapReducejob是Pig生成的。Twitter80%以上是Pig生成的。Linkedin也是。可以看到Pig在这些企业中的应用是非常广的,还有一些其他的主要用户包括SalesforceNokia,相对而言Pig是比较成熟的软件系统,可以完全地把它是用在最终的过程中。

Pig的开发者包括了Hortonworks、Twitter、雅虎、Cloudera。

Pig工具

有不少的用户和开发人员开发了很多套Pig工具,Piggybank是官方的函数库,是跟随Pig一起发行的,Pig主要通过用户来进行维护。第二个是Elephant  bird,它的输入是通过LZO进行的,所以输入不是用Pig传统的文本文件。下面一个是DataFu,是Linkedin的Pig函数库。下面的是Ambros,用户提交了一个Pig脚本,最终会形成一个MapReduce的作业,MapReduce的完成情况都可以通过界面来看到。Mortardata做的是基于云的Pig系统,通过它的界面可以创建一个集群,在那个集群上安装Pig,提交Pig的脚本,直接通过界面进行。

Pig的历史

Pig开发是2006年在雅虎内部进行开发的,2008年雅虎把Pig公开,这个是Pig拉丁语言的所有的系统,整个语言都是根据这篇Paper开发的。第二是Hortonworks把源代码提交给Apache,还做了第一个release。2008年Pig成为Hadoop的子项目。2010年又从Hadoop独立出来,现在是Apache的一级子项目。2012年12月份我们发表了Pig0.8。2011年7月份Hortonworks发布了Pig  0.9.0,里面增加了Embedding。2012年4月份Hortonworks发表了Pig0.10,其中包括了新的数据类型Boolean,现在正在开发的是Pig0.1,这个版本马上就可以发行了,在做最后的功能测试。增加的功能是两个新的操作,一个是数据仓库的操作和Rank的操作。还有新的数据类型Datatime。

Hash  Join的实现

它是最基本的、最流行的Join的方式,在Pig内部Hash Join是怎么实现的。可以看到两个输入文件,第一个输入文件有三个列,第一个列是名字,第二个列是学科,还有分数。之后我们要做的是把这两个表通过名字Join在一起,下面的工作都是在Map阶段做的,首先要把关键字提取出来,也就是说做Join的关键字,第一个表把第一个名字提取了出来。第二个表也是把第一个列提取了出来。然后,做一个tagging,我们把第一个文件编成1,刚才是把key提取出来,现在是加上了tagging。之后通过List可以把第一个输入和第二个输入给分开。所以从第一个文件来的Marry可以放在左边,从第二个文件过来的Marry会放在右边,左边和右边做一个交叉得到的是最后的结果。对Tom来说也是这样的,我们可以很轻易地把它分成两份,之后做一个交叉就得到了最后的结果。

Hash Join的实现

Order by的实现

不是每个Reduce里面实现的排序,我们知道每个Reduce会自动地做一个排序,但我们现在做的是全局的排序。有一种笨办法是只使用一个Reduce,因为只有一个Reduce,所以内部排序就是全局排序,但这种方法是非常愚蠢的,MapReduce是分布式的系统,这样做以后,Reduce就没有用到任何分布式的好处。

Pig内部是如何实现排序?分成两个阶段来做,也就是说通过两个MapReduce来做的,第一个是确定每个Reduce的数据负责的边界,然后确定了数据边界以后会用一个特殊的Partitioner把数据法到不同的Reduce,这个是会自动进行的。通过一个例子来感受一下过程应该是怎样的。输入文件类似,第一个列是名字,第二个列是分数。之后是确定边界的工作,输入的文件会隔多少记录扫描一下,为了让每个Reduce做差不多负荷相同的工作。在这个例子中决定了这个边界是88,也就是说分数小于88个在第一个Reduce里做。这就是第一个MapReduce所需要做的工作,只需要确定边界就行了。下面是第二个MapReduce
job,用的是非常特殊的partitioning,可以感知第一个MapReduce所确定的边界,如果是小于88分往第一个Reduce送。原始输入文件里tom83分会送到第一个reduce,我们每个reduce之间是排完序的,可以保证第一个reduce的值肯定是小于第二个的。有了这个结果以后可以进行每个reduce之间内部的排序。有了内部的排序之后可以得到全局的排序。这就是order by实现的过程。

Order by 的实现

Skewed Join的实现

什么是Skewed Join?MapReduce是一个分布式的处理系统,不同的key会经过map处理以后发往不同的reduce,但是有一种可能是有一个key特别大,因为key是相同的是分不开的,如果有一个特别大会造成一个reduce运行特别缓慢,消耗非常多的内存。我们采取的方式是把超大key也分散到不同的reduce里面做。Pig对skewed  join的是先有三个步骤,第一个是通过Sample。我们主要是确定一下哪些key分配到不同的Reduce,还有超大的key到底需要多少的Reduce来进行。第二,用特殊的Partitioner,可以产生不同的结果需不需要多个reduce,如果需要的话到底有多少?partitioner而会把正确的发送到reduce上面。我们把超大key分开了,这些都是对左边的联系来做的,我们的skill主要指的是左边的。如果要有Pig做Skewed
 join,一定要注意。左边的表进行sample分配到不同的reduce,在reduce阶段可以得到左边的记录,右边的关系是复制到每个reduce,右边的关系每个reduce都会拿到,这样左边的分配好的Key和右边的完整的关系做一个联系。

Merge Join的实现

input文件已经是排序好了的,input是要多次使用和join的,我们先排序,把排序完的文件存起来,以后如果需要可以不停地使用排序完的实验进行Join操作。具体的实现是这样的,左边和右边已经排序完了,但右边的关系还要建立一个索引。有了这个索引在做Join的时候可以很快地找到右边的关系在这个Key的位置。首先是把左边的关系分成不同的部分,因为每个Map会不做不同的部分,右边的关系可以通过第一个Key率先找到位置。这个是map  Side的Join,它的速度是相当快的。

如何充分地利用Combiner

这是Hadoop提供的机制,我们在把数据送往Reduce之前先做一个汇总,这个是通过Combiner提供的。Pig已经进行了Combiner的优化,是不是Combiner是最好的办法减少Map和Reduce的传输量,Combiner所有的map结果会放在disk上,之后再发送到Reduce,中间有一个序列化和反序列化的过程。Pig0.10就对这样的情况做了优化,在Map里面直接做汇总,取消了Combiner。如果汇总的值太多,需要把汇总的结果存在于内存里面,如果汇总的中间结果太大了,内存就不够用了,我们还是要运行在combiner上了。

Pig基于规则的优化器

这个是有一点可以指出的是全局的优化器,SQL是每个语句进行优化的,但Pig的优化器会使整个的Pig进行综合的考虑。在综合考虑的过程中会不断地使用使用不同的规则。Column  pruner,这是在数据库领域里应用很成熟的,如果有一些没有利用到的就可以把它弄掉,当然,拆分以后还有合并。我们有Push down flatten,这些操作越晚进行越好,所以如果有flatten操作就尽量晚做。还有一个是Push up limit,因为它是减少记录的条数。还有一个更好的优化是可以把limit  push到Load里面,我们只Load需要的条数,所以大多数的Load都具有这样的功能,只Load前十条的记录,之后就停止了不再进行更多的记录。之后对Order
 By也是同样的,我们就可以把Limit  push到上面。有一种中间文件是不同的MapReduce之间的中间文件,这种情况下Pig是没有压缩的,为什么Pig中间文件不压缩,主要一个是snappy有问题,我们没有办法作为中间文件压缩,因为Pig中间文件用的是,为什么不用LZO进行压缩,是因为没有Apache的许可证,所以没法儿把LZO压缩包括进来,但是用户可以自行把它括入。如果做这个,用户首先要在这上面压缩LZO。Pig还有一个功能是MapReduce的作业,一个Pig脚本需要很多个MapReduce的job,我们会尝试把集中的作业进行合并。Pig会自动进行作业的合并,只要有可能的话就会合并尽可能多的MapReducejob,再一个MapReduce里进行。但有些情况下我们还是需要控制合并的颗粒度、Pig有时候合并了太多的MapReduce job,这造成了特别慢。这种情况下需要控制一下合并的颗粒度,取消multiquery,这样可以使用命令行参数-M进行取消操作,还有是清晰地表明作业的边界,这就是Pig脚本的例子,如果不做任何事的话。我们MapReduce会做第一个、第二个group
 by。Pig还有一个优化是合并输入文件,这是在某些情况下有一系列的小输入文件,在通常情况下在Hadoop里面每一个输入文件都会Launch一个单独的Map,这样Hadoop系统里就有太多的小的Map作业在跑。Pig做的优化是自动合并这些小输入文件。

Pig0.11的新特性

Cube在0.11里面提供了支持。还有Rank可以进行排序,这个操作以前在Pig里面是没有办法进行的,就算你用UDF也是非常麻烦的。Pig0.1里面包含了一种新的数据类型,Datetime。可以把Pig脚本结合在Jruby里面去,可以把Pig的脚本向前到JRuby脚本里面去。还有一些性能优化,包括SchemaTuple的优化,会动态地产生一些源程序,在动态的阶段进行源程序的编译和执行。当然这还在尝试阶段。还有Local  mode的提高,如果用户想运行一些测试的话,不需要等太长的时间就可以很快地得到了结果。

Pig的发展方向

一个是Low Latency的查询,希望通过一些新特性,可以达到一定程度的提高。下一个是性能优化,包括Cost based optimizer,编译的后端,生成源代码在后端进行编译,最后在0.11里面做了一些尝试但不是很彻底,希望有了经验以后可以更加进行这方面的尝试,基于Hbase的Join优化,可以利用这些特性来优化。还有一个是Visualization和监控,看看有没有更好的图形界面来显示的方法,还有监控系统,Hortonworks Sandbox,Ambari都慢慢地集成进来了。

如何参与Pig开发过程

订阅Pig的邮件列表,有用户的列表。之后可以从贡献Patch开始。PigCommiter一般是活跃6个月以上贡献若干个Patch,会积极地Review其他开发者的Patch,也没有6个月的硬性指标,如果你的贡献很大也不需要呆6个月。

抱歉!评论已关闭.