MapReduce优化

							mapreduce优化

mapreduce跑的慢的原因(io操作优化)
1.map数过多
2.reduce数分配不合理 一般十万的数据量一个reduce就可以了
3.数据倾斜
4.小文件过多
5.spill次数过多(壹写次数过多发生大量本地io)
6.merge次数过多(数据归并且排序)

输入阶段
mapreduce优化主要从6个方面考虑
数据输入,map阶段,reduce阶段,io传输,数据倾斜,常用的网络挑优

数据输入:
①合并小文件,在执行mr程序时将小文件进行合并,大量的小文件会产生大量的map任务(一个文件对应一个map任务),增大map任务装卸次数,而任务的装卸比较耗时,从而导致mr运行较慢
②采用combineTextInputFormat来作为输入,解决输入端大量小文件的场景

Map阶段
1.减少溢写(spill)次数(溢写次数越多越耗时,因为是往本地磁盘写,速度很慢),通过调整io.sort.mb(环形缓冲区大小)及sort.spill.percent(阈值大小)参数值,增大触发spill的内存上限(增大内存),减少spill次数(增大百分比),从而减少磁盘io。
(每次spill都会形成一个spill溢出文件。那么每一次spill会以什么为结束标志?答:就按默认threshold 0.8好了 超过0.8后这已占用的80%全部spill到disk 所以结束标志就是这80%全部spill到disk)
2.减少合并(Merge)次数,通过调整io.sort.factor参数,增大Merge的合并文件数目,从而减少Merge的次数,缩短了mr的处理时间
3.在map之后,不影响业务逻辑的前提下(不能对结果产生影响,适合汇总不适合平均值),先进行combine处理,可以有效的减少网络io(因为combine是在mapshuffle阶段完成溢写到本地之后进行的本地reduce,而reduce shuffle过程在从本地copy到内存缓冲时可以有效的减少拉取资源的次数)
tip:当逻辑一样时则不用reduce直接在job上写上combine.class即可,逻辑不一样时则都需要在job上注明

reduce阶段
1.合理设置map和reduce数:俩个都不能设置的太多或太少,太多则导致map reduce任务间的竞争资源,造成处理超时错误,在装载卸载上也会耗费相当长的时间,设置过少则会导致task等待,延长处理时间。
tip:影响maptask的因素有文件的数量(一个文件对应一个map),文件大小(文件大于128会启动1个以上的map任务),配置参数(splitSize = Math.max(minSize, Math.min(maxSize, blockSize)))
2.设置map reduce共存,调整slowstart。completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce等待时间。(相当于reduce提前参与运算,不等所有的maptask结束,其中几个maptask结束就可以运行reducetask,后面的maptask结束在运行)
3.规避使用reduce,因为reduce在用于连接数据集的时候会产生大量的网络消耗
4.设置合理的reduce端的buffer(reduce端的默认大小是48MB),默认情况下,数据达到一个阈值时,buffer中的数据就会写入磁盘中,然后reduce就会从磁盘中获得所有的数据,也就是说,Buffer与reduce没有直接关联,中间有多次写磁盘,读磁盘的过程,那么可以通过参数配置使得buffer中的数据直接输送到reduce端,从而减少io的开销:maperd.job.reduce.input.buffer.percent,默认为0.0,当值大于0时会保留指定比例的内存读buffer中的数据直接拿给reduce使用。(注意:内存不够用就不要开,内存是双刃剑,并不是开的越多越好)

io传输
1.采用数据压缩的形式可以减少网络io的时间,安装Snappy和LZO压缩编码器。(企业中用这俩种使用率非常高)
2.使用SequenceFile二进制文件。(这种格式比较紧凑)

数据倾斜
如何产生的?

根据MapReduce的执行流程以发现,在map端是不会产生数据倾斜的,因为它会根据分片规则将数据进行均匀的切分成一个个固定大小的数据片段,而且每一个数据片段都会有一个maptask去处理,因此,数据倾斜只会在reduce端产生,因为map程序会将数据处理成键值对的形式,这样就有可能出现有的键相同的数据多,有的键相同的数据少。因此在进行partition分区的时候会将键相同的数据分配到同一个reduce当中去,这样就会导致有的reduce要处理数据会很多,有的就会很少,从而导致数据倾斜问题的产生。所以我们需要根据实际数据的特点自定义partition分区的规则,这样就能很好的解决数据倾斜的问题。
数据倾斜是数据中的常见情况。数据中不可避免地会出现离群值(outlier),并导致数据倾斜。这些离群值会显著地拖慢MapReduce的执行。常见的数据倾斜有以下几类:

数据频率倾斜——某一个区域的数据量要远远大于其他区域。
数据大小倾斜——部分记录的大小远远大于平均值。

优化方案:
1.抽样和范围分区
可以通过对原始数据进行抽样得到的结果集来预设分区边界值
例如:假如我有2亿条数据,先拿出一部分数据,例如拿一千万吧,咱对一千万条数据进行分析,分析这一千万条分多少区合适,如果按照mr框架的设计,按照key的hash数据量可能会非常大,里面有900万条相同类型的数据,之后根据900万条数据的特点将他们打散,把key拼接点随机数(hive和hbase同样适用 先抽取样本试一试)
2.自定义分区
基于输出键的背景知识进行自定义分区,例如:如果map输出键的单词来源于一本词典,且其中某个具体词汇较多,那么就可以自定义分区将这些专业词汇发往固定的一部分reduce实例,而将其它的都发送给剩余的reduce
3.使用combine可以大量的减小数据频率倾斜和数据大小倾斜,combine就是聚合并精简数据

业务逻辑,我们从业务逻辑的层面上来优化数据倾斜,我们单独对这两个城市来做count,最后和其它城市做整合。
程序层面,比如说在Hive中,经常遇到count(distinct)操作,这样会导致最终只有一个reduce,我们可以先group 再在外面包一层count,就可以了。
调参方面,Hadoop和Spark都自带了很多的参数和机制来调节数据倾斜,合理利用它们就能解决大部分问题。
解决数据倾斜的重点在于对数据设计和业务的理解,这两个搞清楚了,数据倾斜就解决了大部分了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值