打赏

MapReduce跑的慢的原因

MapReduce程序效率的瓶颈在于两点:

1.计算机性能

CPU、内存、磁盘健康、网络。

2.I/O操作优化

①数据倾斜

②Map和Reduce数设置不合理

③Map允许时间太长,导致Reduce等待太久

④小文件过多

⑤大量的不可切片的超大压缩文件

⑥Spill次数过多

⑦Merge次数过多

从数据输入端优化:

(1)合并小文件:在执行MR任务前将小文件进行合并,大量的小文件会产生大量的Map任务,增大Map任务的装载次数,而任务的装载比较耗时,从而导致MR允许比较慢。

(2)采用CombineTextInputFormat来作为输入,解决输入端大量小文件场景。

Map阶段优化:

(1)减少溢写次数:通过调整mapreduce.task.io.sort.mb及mapreduce.map.sort.spill.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO。

(2)减少合并次数:通过调整mapreduce.task.io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。

(3)在Map之后,不影响业务逻辑前提下,先进行Combine处理,减少I/O。

Reduce阶段优化:

(1)合理设置Map和Reduce数:两个都不能设置太少,也不能设置太多;太少,会导致Task等待,延长处理时间,太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。

(2)设置Map、Reduce共存

调整mapreduce.job.reduce.slowstart.completedmaps参数,使Map运行到一定程度后,Reudce也开始运行,减少Reduce的等待时间。

(3)规避使用Reduce

因为Reduce在用于连接数据集的时候会产生大量的网络消耗。

(4)合理设置Reduce端的Buffer

默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有的数据。也就是说,Buffer和Reduce是没有直接关联的,中间多次写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得Buffer中的一部分数据可以直接输送到Reduce,从而减少IO开销:mapreduce.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来,设置Buffer需要内存,读取数据需要内存,Reduce计算也要内存,所以要根据作业的运行情况进行调整。

 

posted @ 2022-02-16 21:16  不像话  阅读(571)  评论(0编辑  收藏  举报