Hadoop vs ODPS之: MapReduce任务数目

我会写一系列短文,分析Hadoop和我们的ODPS产品的一些特性对比,希望从中可以简单理一下Hadoop和ODPS设计上的一些思路异同。

水平有限,疏漏处请见谅。

本篇讲MapReduce作业的Map和Reduce任务数量的配置。

Hadoop

Map 任务数量

Map个数等同于最终切片个数,即: 输入数据大小/最终splitSize

最终splitSize怎么来呢,算法是这样:

MAX(minSize, Min(maxSize, blockSize))

其中minSize是最小切片大小,maxSize是用户指定的最大切片大小,blockSize是文件分块大小。

minSize = Max(mapred.min.split.size, minSplitSize)

这里为什么会有两个min?是因为一个是固有min,一个是用户指定的配置参数。

maxSize是mapreduce.input.fileinputformat.split.maxsize这个配置项。

详细代码参见org.apache.hadoop.mapreduce.lib.input.FileInputFormat。

Reduce 任务数量

通过Job.setNumReduceTasks(int tasks)可以指定数量,如果不指定默认是1个。

官方推荐的设置公式是如下:

0.95*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum

1.75*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum

其中 NUMBEROFNODES 指的是集群节点数,mapred.tasktracker.reduce.tasks.maximum指的是一个节点上reducer 的最大槽数。

我理解,0.95意味着更倾向于并发和负载的平衡,1.75更强调并发。

ODPS

Map

其实基本思路是一样的。用户无法直接设置Map的Worker数量,是通过配置分片大小参数来影响Map个数:

set odps.stage.mapper.split.size=?

Reduce

默认情况下,单个作业中,ODPS 的Reduce任务的个数是Map任务数的1/4。

可以通过如下设置修改reducer个数。

set odps.stage.reducer.num=?

对比说明

我们可以看到,其实两者在思路上没有太大区别:

  • 都是根据输入数据量自动划分Map个数,用户可以利用分片大小配置来影响Map个数;
  • 都是可以直接定制Reduce个数。

但是对于Map配置而言,Hadoop相对ODPS略嫌复杂(不过差别也不大); 而对于Reduce配置而言,ODPS的默认1/4个Map数目的做法更易用。Hadoop推荐的计算公式并不一定真的适用,因为计算任务和机器硬件配置都是千变万化的。

其实对于作业的并发度的这种调优并不是一件容易的事情,相对而言,对于根据数据输入和任务类型自动调整任务个数的能力,我更信赖ODPS,毕竟是阿里内部大量作业夜以继日运行喂出来的结果。

Footnotes:

1 这里以2.6版本,新版本MapReduce框架为例。旧MapReduce框架算法有所不同,不再详细说明。
2 还有一些特殊逻辑,比如使用HBase时,map的数目等于表的region数目。
3 Hadoop把节点看做若干逻辑上的槽位,每个槽位可以容纳一个Mapper或Reducer。这是一种比较简单的计算能力划分。
4 ODPS还有一种配置是设置joiner数目,因为ODPS在设计时更倾斜于SQL,把Join操作也设定为一种特殊的任务类型。不过MapReduce框架不涉及joiner(虽然也能用MR实现Join逻辑)。


最后更新: 2015-12-01 18:41