hadoop之 mapreduce data flow

来源:互联网 发布:java中接口 知乎 编辑:程序博客网 时间:2024/05/29 04:37

注:随笔 取自于 hadoop权威指南第四版

Hadoop 会讲MapReduce输入的数据切分成大小相等的数据块(fixed-size 固定大小,我认为翻译成相等大小比较合适),或者称之为分片。Hadoop会未每一个分片创建一个map 任务,并由该任务来运行用户自定义的map函数。

一个输入数据可以切分成许多切片,我们可以使用map并行处理这些切片,缩短整个任务处理过程的时间。当然分片并不是切分的越小越好,越多的分片就需要花费越多的时间去管理分片以及 增加构建map的时间。然而对于大多数的作业来说,比较合理的方式是 分片的大小是等于 block size。

如果在存有数据集的节点上运行map任务,hadoop将会获得更好的性能,因为这无需使用集群的带宽资源。这被称为data locality optimization。但是,有时候会有这么一种情况,当前map任务的输入数据存储的三个HDFS节点上都有其他map任务在运行,此时,作业调度会在三个备份中的某个数据寻求同个机架中空闲的机器运行该map任务。当然如果未寻找到合适的机器,会使用其他机架中的机器运行该map任务,不过这种情况发生的概率比较小。下图展示了这三种可能性。

It should now be clear why the optimal split size is the same as the block size: it is the largest size of input that can be guaranteed to be stored on a single node.
分片的大小不超过block size,可以确保输入的数据存储在单个节点上。如果分片跨越两个数据块,在一个HDFS节点上,几乎不可能同时存储这两个block,那么部分输入数据需要通过网络进行传输。与使用本地数据相比,这种方法明显不够明智。

Map 函数产生的中间文件不会写入HDFS,而是写在了本地。原因是map输出的是中间结果,需要经过reduce的处理后才能产生最终结果。当作业完成时,map输出的结果可以删除。因此,如果将中间结果存储在HDFS并备份,overkill(过度,或者叫小题大做)。如果该节点运行的map任务在将结果传输到reduce之前失败,hadoop会自动在其他节点重现运行map任务,并产生中间结果。

reduce任务并不具备本地化优势。单个的reduce任务的输入通常来自于所有mapper的输出。在http://www.cnblogs.com/re-myself/p/5518283.html 例子中,只有一个reduce任务,其输入是所有map任务的输出。经过排序的map输出需通过网络传输发送到运行reduce任务的节点,并在reduce函数中进行合并、运算。reduce的输出结果存储在HDFS中。reduce输出时,第一个replica 会存储在本地节点,其他replica会存储在其他的机架节点中。因此,reduce输出肯定会占用网络带宽,但是和正常的写入消耗是一样的。
下图是一个reduce任务的 MapReduce 数据流

reduce任务的数量并非由输入数据决定,需要独立指定。
the map tasks partition their output, each creating one partition for each reduce task
如果有多个reducers,map会将其输出进行分区,每一个reduce任务都会创建一个分区。每个分区都会有许多个键(还有其对应的值),但是每个键值对记录都在同一个分区中(There can be many keys (and their associated values)in each partition, but the records for any given key are all in a single partition)。分区由用户定义partition函数控制。默认的partitioner是通过hash函数分区。

上图未多个reduce任务的数据流图

mapreduce可以没有reduce。数据处理可以完全并行,不需要shuffle。在这种情况下,唯一的非本节点的传输是map任务将结果写入HDFS。(In this case, the only off-node data transfer is when the map tasks write to HDFS)

0 0
原创粉丝点击