-
MapReduce作业是客户端需要执行的一个工作单元:它包括输入数据、mapreduce程序和配置信息。Hadoop将作业分成若干个任务来执行,其中包括两类任务:map任务和reduce任务。
-
数据流
- Hadoop将mapreduce的输入数据划分成等长的小数据块,成为输入分片。一个分片对应一个map任务。一个合理的分片大小趋向于HDFS一个块的大小,默认是128MB,可调整;
- Hadoop在存储有输入数据的节点上运行map任务,可以获得最佳性能,因为无须消耗网络带宽资源,这就是“数据本地化优化”。但是对于一个map任务的输入分片来说,存储该分片的所有节点可能正在运行其他map任务,此时需要在该分片所在的机架中寻找一个空闲的map槽来运行该map任务;
- 为什么最佳分片大小与HDFS一个块的大小相同?因为它是确保可以存储在单个节点上的最大输入块的大小。如果分片跨越两个数据块,那么对于任何一个HDFS节点,基本上不可能同时存储这两个数据块,因此分片中的部分数据需要通过网络传输到map任务运行的节点,降低了效率;
- reduce并不具备数据本地化优势,单个reduce任务的输入通常来自于所有mapper的输出。对于reduce输出的每个HDFS块,第一个复本存储在本地节点,其他复本处于可靠性考虑存储在其他机架的节点中;
- reduce的数量并非是由输入数据的大小决定的,相反是单独指定的。如果由很多个reduce任务,每个map任务就会针对输出进行分区,即为每个reduce任务建一个分区。每个分区有许多键(及其对应的值),但每个键对应的键-值对记录都在同一个分区。分区可由用户自定义的分区函数控制,默认通过哈希函数来分区;
- map任务和reduce任务之间的数据流成为shuffle。当数据处理可以完全并行时,可能会出现无reduce的情况,此时唯一的非本地节点数据传输是map任务将结果写入到HDFS。
-
combiner函数
-
为了节省带宽,减少map任务与reduce任务间的数据传输量,Hadoop允许用户针对map任务的输出指定一个combiner,combiner函数的输出作为reduce任务的输入。且不管调用combiner多少次,reduce的输出结果都是一样的。
- 例如:在求最高气温的例子中,没有combiner时map1输出:(1950,0)(1950,20)(1950,10),map2输出:(1950,25)(1950,15),reduce函数被调用时,它的输入为(1950,[0,20,10,25,15]),我们可以指定combiner函数,找出每个map任务输出结果中的最高气温,如此一来,reduce函数的输入变成了(1950,[20, 25])。
-