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 也同样部署到同一台机器上。