MapReduce性能优化

目录

Map和Reduce中优化

1、 读取数据产生多少个Mapper??

Mapper数据过大的话,会产生大量的小文件,由于Mapper是基于虚拟机的,过多的Mapper创建和初始化及关闭虚拟机都会消耗大量的硬件资源;

Mapper数太小,并发度过小,Job执行时间过长,无法充分利用分布式硬件资源;

2、Mapper数量由什么决定??

(1)输入文件数目

(2)输入文件的大小

(3)配置参数

这三个因素决定的。

涉及参数:

mapreduce.input.fileinputformat.split.minsize //启动map最小的split size大小,默认0

mapreduce.input.fileinputformat.split.maxsize //启动map最大的split size大小,默认256M

dfs.block.size//block块大小,默认64M

计算公式:splitSize = Math.max(minSize, Math.min(maxSize, blockSize));

例如默认情况下:例如一个文件800M,Block大小是128M,那么Mapper数目就是7个。6个Mapper处理的数据是128M,1个Mapper处理的数据是32M;

再例如一个目录下有三个文件大小分别为:5M10M 150M 这个时候其实会产生四个Mapper处理的数据分别是5M,10M,128M,22M。

Mapper是基于文件自动产生的,如果想要自己控制Mapper的个数???

就如上面,5M,10M的数据很快处理完了,128M要很长时间;这个就需要通过参数的控制来调节Mapper的个数。

减少Mapper的个数的话,就要合并小文件,这种小文件有可能是直接来自于数据源的小文件,也可能是Reduce产生的小文件。

设置合并器:(set都是在hive脚本,也可以配置Hadoop)

设置合并器本身:

 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; set hive.merge.mapFiles=true; set hive.merge.mapredFiles=true; set hive.merge.size.per.task=256000000;//每个Mapper要处理的数据,就把上面的5M10M……合并成为一个

一般还要配合一个参数:

 set mapred.max.split.size=256000000 // mapred切分的大小 set mapred.min.split.size.per.node=128000000//低于128M就算小文件,数据在一个节点会合并,在多个不同的节点会把数据抓过来进行合并。

Hadoop中的参数:可以通过控制文件的数量控制mapper数量

 mapreduce.input.fileinputformat.split.minsize(default:0),小于这个值会合并 mapreduce.input.fileinputformat.split.maxsize大于这个值会切分

如果能够根据情况对shuffle过程进行调优,对于提供MapReduce性能很有帮助。相关的参数配置列在后面的表格中。

一个通用的原则是给shuffle过程分配尽可能大的内存,当然你需要确保map和reduce有足够的内存来运行业务逻辑。因此在实现Mapper和Reducer时,应该尽量减少内存的使用,例如避免在Map中不断地叠加。

运行map和reduce任务的JVM,内存通过mapred.child.java.opts属性来设置,尽可能设大内存。容器的内存大小通过mapreduce.map.memory.mb和mapreduce.reduce.memory.mb来设置,默认都是1024M。

map优化

在map端,避免写入多个spill文件可能达到最好的性能,一个spill文件是最好的。通过估计map的输出大小,设置合理的mapreduce.task.io.sort.*属性,使得spill文件数量最小。例如尽可能调大mapreduce.task.io.sort.mb。

map端相关的属性如下表:

reduce优化

在reduce端,如果能够让所有数据都保存在内存中,可以达到最佳的性能。通常情况下,内存都保留给reduce函数,但是如果reduce函数对内存需求不是很高,将mapreduce.reduce.merge.inmem.threshold(触发合并的map输出文件数)设为0,mapreduce.reduce.input.buffer.percent(用于保存map输出文件的堆内存比例)设为1.0,可以达到很好的性能提升。在2008年的TB级别数据排序性能测试中,Hadoop就是通过将reduce的中间数据都保存在内存中胜利的。

reduce端相关属性:

通用优化

Hadoop默认使用4KB作为缓冲,这个算是很小的,可以通过io.file.buffer.size来调高缓冲池大小。

随机文章