1.整个MapReduce计算过程分为 Map 阶段和 Reduce阶段,也称为映射和缩减阶段,

这两个独立的阶段实际上是两个独立的过程,即 Map 过程和 Reduce 过程,

在 Map 中进行数据的读取和预处理,之后将预处理的结果发送到 Reduce 中进行合并


2.MapReduce 执行流程

input -> map -> middle result Shuffle 派发 -> reduce -> output

1)nput阶段: 

split内容分片形成一系列的 InputSplit,每个 InputSplit 都由一个 mapper 进行后续处理。

分片大小splitSize 由三个值来确定:

minSize:splitSize 的最小值,由 mapred-site.xml 配置文件中mapred.min.split.size 参数确定。

maxSize:splitSize 的最大值,由 mapred-site.xml 配置文件中mapreduce.jobtracker.split.metainfo.maxsize 参数确定。

blockSize:HDFS 中文件存储的快大小,由 hdfs-site.xml 配置文件中dfs.block.size 参数确定。

splitSize 的确定规则:splitSize=max{minSize,min{maxSize,blockSize}}

2)map阶段:

将划分好的 InputSplit 格式化成键值对形式的数据。其中 key 为偏移量,value 是每一行的内容。

每生成一个键值对就会将其传入 map,进行处理。所以 map 和数据格式化操作并不存在前后时间差,而是同时进行的

map 输出的结果会暂且放在一个环形内存缓冲区中(该缓冲区的大小默认为 100M,由 io.sort.mb 属性控制),

当该缓冲区快要溢出时(默认为缓冲区大小的 80%,由io.sort.spill.percent属性控制),

会在本地文件系统中创建一个溢出文件,将该缓冲区中的数据写入这个文件

在写入磁盘之前,线程首先根据reduce任务的数目将数据划分为相同数目的分区,也就是一个 reduce任务对应一个分区的数据。

如果此时设置了 Combiner,将排序后的结果进行 Combine 操作,这样做的目的是让尽可能少的数据写入到磁盘。

3)Shuffle 派发:

Shuffle 过程是指 Mapper 产生的直接输出结果,经过一系列的处理,成为Reducer直接输入数据为止的整个过程

该过程可以分为两个阶段:

Mapper 端的 Shuffle:

先存储在内存中,当内存中的数据量达到设定的阀值时,一次性写入到本地磁盘中。

并同时进行sort(排序)、combine(合并)、partition(分片)等操作。

sort 是把 Mapper 产生的结果按照 key值进行排序;

combine是把key值相同的记录进行合并;

partition是把数据均衡的分配给 Reducer。

Reducer 端的 Shuffle:

由于 Mapper 和 Reducer 往往不在同一个节点上运行,所以Reducer 需要从多个节点上下载 Mapper 的结果数据

4) Reduce 缩减:

Reduce 会接收到不同 map 任务传来的数据,并且每个 map 传来的数据都是有序的。

如果 reduce 端接受的数据量相当小,则直接存储在内存中(缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制), 

如 果 数 据 量 超 过 了 该 缓 冲 区 大 小 的 一 定 比 例 ( 由mapred.job.shuffle.merge.percent 决定),则对数据合并后溢写到磁盘中。

每个 reduce 进程会对应一个输出文件,名称以 part-开头。


3.MapReduce计算框架中负责计算任务调度的JobTracker对应HDFS的NameNode的角色,只不过一个负责计算任务调度,一个负责存储任务调度。MapReduce计算框架中负责真正计算任务的TaskTracker对应到HDFS的DataNode的角色,一个负责计算,一个负责管理存储数据。

考虑到“本地化原则”,一般地,将 NameNode 和 JobTracker 部署到同一台机器上,各个 DataNode 和 TaskNode 也同样部署到同一台机器上。