pig中hadoop参数设置(详解pig.maxCombinedSplitSize 和 pig.splitCombination)

转载自:https://blog.csdn.net/strongerbit/article/details/7205929

     https://blog.csdn.net/xiaolang85/article/details/8651894

hadoop job 重要性能参数

name说明
mapred.task.profile是否对任务进行profiling,调用java内置的profile功能,打出相关性能信息
mapred.task.profile.{maps|reduces}对几个map或reduce进行profiling。非常影响速度,建议在小数据量上尝试
mapred.job.reuse.jvm.num.tasks1表示不reuse,-1表示无限reuse,其他数值表示每个jvm reuse次数。reuse的时候,map结束时不会释放内存!
mapred.{map|reduce}.tasks.speculative.execution会对运行慢的任务起一个备份任务,看哪个先完成,kill掉后完成的备份
io.sort.spill.percent开始spill的内存比例阈值,对map和reduce都生效
mapred.job.shuffle.input.buffer.percentreduce在copy时使用的堆空间的比例
mapred.tasktracker.{map|reduce}.tasks.maximum一个Tasktracker上可同时运行的最大map、reduce任务数
mapred.reduce.copy.backoffreduce获取一份map输出数据的最大时间,单位秒。
io.compression.codecs压缩算法
dfs.block.sizehdfs上的文件block大小
mapred.reduce.slowstart.completed.maps控制reduce的启动时机。表示全部map的百分之多少完成后,才启动reduce。如果机器内存紧张,可以适当设大改参数,等大部分map结束并释放内存后才启动reduce;如果希望尽快开始shuffle,则可配合大量map数,将该值设小,以尽早启动reduce,开始copy。
io.sort.mbmap使用的缓存,影响spill的次数。
mapred.child.java.opts同时设置map和reduce的jvm参数
mapred.map.child.java.opts分开设置map的jvm参数,包括GC策略
mapred.reduce.child.java.opts分开设置reduce的jvm参数
map.sort.class对map的输出key的排序方法
mapred.output.compression.type压缩类型
mapred.min.split.size每个map的最小输入大小,该值越大,map数越少
mapred.max.split.size每个map的最大输入大小,该值约小,map数越多
mapred.reduce.parallel.copiesreduce从map结果copy数据时,每个reduce起的并行copy线程数。该值越大,io压力越大,但可能引起网络堵塞,copy效率反而降低。
io.sort.factormerge时的并行merge数,同时影响map的spill文件merge和reduce中的merge
mapred.compress.map.output指定map的输出是否压缩。有助于减小数据量,减小io压力,但压缩和解压有cpu成本,需要慎重选择压缩算法。
mapred.map.output.compression.codecmap输出的压缩算法
mapred.output.compressreduce输出是否压缩
mapred.output.compression.codec控制mapred的输出的压缩的方式
io.sort.record.percentmap中间数据的index和data在io.sort.mb中占内存的比例,默认0.05%,需要根据具体数据的特点调整:index的大小固定为16byte,需要根据data的大小调整这个比例,以使io.sort.mb的内存得到充分利用)。


部分参数详解:

1. pig.maxCombinedSplitSize 和 pig.splitCombination

在实际使用PIG处理数据时,会经常要处理大批量的小文件。在这种情况下,如果不对Pig脚本进行任何特别设置,默认情况下很有可能会遇到类似这样的“命名空间超过配额限制”的错误:

  1. org.apache.hadoop.hdfs.protocol.NSQuotaExceededException: org.apache.hadoop.hdfs.protocol.NSQuotaExceededException:   
  2. The NameSpace quota (directories and files) of directory /projects/user_grid is exceeded: quota=1000000 file count=1000001  

或者如果你发现,你的Pig脚本运行结果会产生数量巨大的输出文件(通常在没有reduce时),比如几万甚至几十万个文件输出,则这条经验应该能解决你的问题。

出现这种问题的原因就是由于在处理数据过程中,Pig为每一个输入文件都创建了一个相应的mapper,每个mapper就会产生相应的一个输出文件。这种行为当然是正确的,也是Hadoop框架的设计所要求的,因为Hadoop框架会为每个data block创建一个mapper,如果一个文件小于dfs.block.size(默认为64M),则此文件会独占一个block,不与别的文件共享该data block。这种默认行为对于输入data block数量(或者文件数量)巨大的情况下,代价会非常昂贵,执行效率非常低。解决方案很自然就是将data block做适当的合并,然后为合并后的每个split创建一个mapper。

在Pig 0.80之后的版本,Pig提供了能够合并多个输入文件生成一个split的功能。当在Pig脚本中设置了



  1. SET pig.splitCombination true;  
  2. SET pig.maxCombinedSplitSize 134217728; -- 134217728 = 128M  
SET pig.splitCombination true;
SET pig.maxCombinedSplitSize 134217728; -- 134217728 = 128M

后,Pig在运行mapper之前,首先会把小于128M的小文件都合并成128M之后,再创建与之对应的mapper。如果没有设置maxCombinedSplitSize,则Pig会自动按照HDFS的block size合并小文件。如果需要将自动合并小文件的功能关闭,只需要 ‘SET pig.splitCombination false;’ 即可。根据目前我的经验,至少Pig 0.91版本默认 pig.splitCombination为false。

从实现原理上讲,当设置了pig.splitCombination为true之后,Pig将使用CombinedInputFormat来读取输入,使用CombinedInputSplit实例而非默认的InputSplit实例。CombinedInputFormat用来代替即将弃用的MultiFileInputFormat,会基于data block的locality特性批量合并小文件。在Pig内部,如果输入Input的locality(位置)信息不可用,那么此接口也能正常工作。因此combined input format将有多个通用的split合并而成,直到合并的size达到pig.maxCombinedSplitSize或者dfs.split.size。

然而由于在merge join table中排序的限制,split combination将不会用在任何有merge join的地方。但是在map阶段的cogroup和map阶段的group by,那些split会被合并,因为在map阶段的这些操作,仅仅要求被合并的数据保留重复的key,combine并没有影响到重复key这些要素。在合并过程中,在同一节点上的split尽可能的被合并,剩下未合并的split将不会考虑locality因素而拷贝到其他node上去合并。在每个结点上,将会采用贪婪的方法合并,最大的split会优先于小的split合并。


2. maxCombineSplitSize设置为多少效率最好?

本地执行job占全部job的比例越高,则执行速度越快。在Job tracker的监控web页面中,会有一个summary页面显示该job的各项数据,在Job Counter一栏中有Rack-local map tasks、Launched map tasks、Data-local map tasks三项数据,分别表示在同一个机柜中执行的map task数目,启动的map task数目,本地执行的map task数目。在这个summary页面的上方,还会显示successful map tasks,表示最终成功执行的map task数目。我们可以简单的用 data-local map tasks / successful map tasks = 本地执行的map tasks的比例作为指标来衡量在map阶段的效率。

我测试了一下,输入是10T的二进制日志数据,做一般字段的抽取,输出为table分割的文本,没有reduce操作,hadoop集群有2773个Map slot可用测试结果如下:

maxCombineSplitSizeData-local Map TasksSuccessful Map TasksExecution DurationRatio
3600000000202632843H 19' 30''2026/3807 = 0.532
4250000000158027723H 28' 27''1580/2805 = 0.563
2000000000428356202H 31' 59''4283/6396 = 0.6696
10000000008729109642H 4' 39''8729/12386 = 0.7047
51200000020200238061H 57' 4''20200/23806 = 0.8489

单纯从map的速度而言,如果不是大多数文件size都大大小于dfs.block.size,如果输出的文件数目能够接受且不会产生异常的情况下,当然是每个block对应一个mapper的效率最高了。如果是文件数目过多(即便每个文件都大于dbf.block.size),整个过程中没有reduce操作,那么每个block对应一个mapper会导致输出大量文件,撑爆hdfs的name space。在实际中应该本着不会产生异常的情况下,使得本地执行job的比例尽量高的目标去设置maxCombineSplitSize。


3. mapred.map.tasks.speculative.execution和mapred.reduce.tasks.speculative.execution

在使用Pig处理大批量数据时,通常是T级别及以上的情况下,你会发现当pig job被提交后,起初执行速度还挺不错,但是到了90%之后,job的执行就如同蜗牛在爬行。打开job tracker的页面,点开running链接,看看正在执行的task是什么时候启动的,你就会发现,原来这些拖后腿的task原来大多数很早就被启动执行了。就是因为这些task导致整个job在后期执行非常缓慢。那么这种情况下,你需要打开mapred的speculative开关为true,Map-Reduce框架就会侦测执行缓慢的task,启动新的task做相同的事情,最终把拖后腿的task都kill掉,从而有效的提高了pig job的执行速度。


  1. SET mapred.map.tasks.speculative.execution true;  
  2. SET mapred.reduce.tasks.speculative.execution true;  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值