1 概述
MapReduce是一个高度抽象的大数据作业执行组件,整个作业过程主要有两个,分别是map与reduce,本文主要介绍MapReduce中的map与reduce任务数设置的方式,以及如何合理的设置map与reduce的任务数。
2 从源码入手分析
(1)分析JobSubmitter 任务提交类
JobStatus submitJobInternal(Job job, Cluster cluster) {
......
//计算切片数量
int maps = writeSplits(job, submitJobDir);
//将切片数量设置为map任务数
conf.setInt(MRJobConfig.NUM_MAPS, maps);
......
}
说明:此任务提交方法中首先通过writeSplits函数计算出切片的数量,然后将切片数量设置为map任务数
(2)分析FileInputFormat 基于文件的输入格式化类
public List<InputSplit> getSplits(JobContext job) {
......
long splitSize = computeSplitSize(blockSize, minSize, maxSize);
......
}
说明:getSplits为具体的切片算法函数
computeSplitSize函数计算出每次要切割的字节数splitSize,具体算法如下:
Math.max(minSize, Math.min(maxSize, blockSize))
算法思想为:
(1)如果maxSize小于blockSize,那么每次就以maxSize个字节为切割的字节数
(2)如果maxSize大于blockSize,那么每次就以blockSize个字节为切割的字节数
例如:输入文件大小总共为28个字节(回车与换行符占2个字节),内容如下:
hello how are
thank you tom
其中maxSize = 15,minSize = 10,blockSize为默认块大小131072字节,计算得出每次以 15 个字节为切割的字节数,那么28个字节总共被分为2片,及最终产生2个map任务。
blockSize:HDFS块大小,以字节为单位(Hadoop 2.0 默认块大小为128M)
minSize:mapreduce.input.fileinputformat.split.minsize (文件的最小切割字节数)
maxSize:mapreduce.input.fileinputformat.split.maxsize (文件的最大切割字节数)
3 自定义map任务数
通过上面的源码分析,可以得出影响map任务数的因素主要由三个参数,blockSize、minSize、maxSize,那么我们可以通过配置这几个参数就可以自定义map任务数了。自定义map任务数的方式有多种
3.1 方式一:通过配置文件配置map任务数
修改mapred-site.xml文件,添加如下配置
<property>
<name>mapreduce.input.fileinputformat.split.minsize</name>
<value>10</value>
</property>
<property>
<name>mapreduce.input.fileinputformat.split.maxsize</name>
<value>15</value>
</property>
3.2 方式二:通过程序中设置map任务数
FileInputFormat.setMinInputSplitSize(job, 10);
FileInputFormat.setMaxInputSplitSize(job, 15);
4 自定义reduce任务数
通过Job的setNumReduceTasks(3) 方法来设置reduce的任务数
5 合理设置map任务数
一定数量的map任务数可以提高作业的执行速度,因为这些map任务是完全并行处理的,那到底设置多少map任务数比较合理呢?Hadoop官方建议一般每个节点上保持10-100个map任务数,也可以根据cpu的使用率设置更高的数目,但是前提是每个map任务的执行时间需要1分钟以上,因为任务的启动是需要花费一定时间的,如果map任务的执行时间小于任务的启动时间,那么设置了过多的map任务反而导致效率较低。
6 合理设置reduce任务数
Hadoop官方建议设置reduce任务数为:0.95 或 1.75 * (节点数 * mapreduce.tasktracker.reduce.tasks.maximum 数)
(1)如果是乘以0.95的话,那么在map任务执行完成后立即启动所有的reduce任务
(2)如果是乘以1.75的话,那么将会分两次启动所有的reduce任务,这样可以更好的完成map到reduce的负载均衡
过多的reduce任务数会增加系统的开销,从而影响整个作业的执行效率,但是却可以更好的完成负载均衡与较低失败的成本。
7 总结
本文主要从源码的角度简单分析了MapReduce的切片过程、map与reduce任务数的设置方法、以及如何正确合理的配置map与reduce任务数,如有疑问的地方请留言!