大数据框架MapReduce的map与reduce任务数合理设置

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任务数,如有疑问的地方请留言!

猜你喜欢

转载自my.oschina.net/feinik/blog/1649474