概述
Hadoop MapReduce是一个软件框架,用于轻松编写应用程序,以可靠,容错的方式在大型集群(数千个节点)的商用软件上并行处理大量数据(多是TB级的数据集)。
MapReduce作业通常将输入数据集拆分为独立的块,这些块由Map任务以完全并行的方式处理。框架对Map的输出进行排序,然后输入到Reduce任务。通常,作业的输入输出都存储在文件系统中。该框架负责调度任务,监视任务并重新执行失败的任务。
通常,计算节点和存储节点是相同的。即MapReduce框架和HDFS在同一组节点上运行。此配置允许框架有效地在已存在数据的节点上调度任务,从而在集群中产生非常高的聚合带宽。
MapReduce框架由单个主ResourceManager,每个集群节点一个从NodeManager和每个应用程序的MRAppMaster组成。也就是YARN的架构。
最低限度,应用程序通过实现适当的接口或者抽象类来指定输入/输出位置并提供map和reduce功能。这些和其他作业参数,由作业配置组成。
然后,Hadoop作业客户端将作业(jar/可执行文件等)和配置提交给ResourceManager,ResourceManager负责将软件/配置分发给从服务(NodeManager),调度任务并监控它们,提供状态和诊断信息给作业客户端。
MapReduce框架专门用于<key,value>
对,也就是说,框架将作业的输入视为一组<key,value>
对,并生成一组<key,value>
对作为输出。
运行机制
从广义上讲,MapReduce分为两部分:Map是映射,负责数据的过滤分发;Reduce是规约,负责数据的计算归并。
但是在MapReduce框架中有一个最关键的流程叫Shuffle,这个流程决定了map阶段处理的数据如何传递给reduce阶段。
所以从细节上来看,个人认为MapReduce的运行主要分为三个部分,分别为:map阶段、shuffle过程和reduce阶段。
这时可以认为,map阶段是为并行计算准备数据;shuffle过程真正进行并行计算,包含map端和reduce端两部分;reduce阶段是将计算结果写入HDFS。
下面简单说一下我对这三个部分的理解。
map阶段
map阶段就是将一个文件分成若干个部分,每个部分对应一个map任务,然后为进行并行计算做准备,这样在计算的时候就会极大的缩短完成时间。不过也不是map任务数越多越好。
在进行map计算之前,mapreduce会根据输入文件计算输入分片(input split),也就是拆分文件,一般来说分片的大小和hdfs的block大小相同,每个输入分片对应一个map任务。
一个分片就是一个map准备的数据。
shuffle过程
map输出到reduce输入这中间的处理过程就是shuffle过程。shuffle过程是整个处理流程的重头戏,也是优化的重点。
shuffle过程包括map端的spill以及reduce端的copy和sort。
所以这里可以把shuffle阶段分为两部分来看,分别是map端和reduce端。
map端
在map端的shuffle过程是spill。
map任务处理输入数据并产生中间结果,这个中间结果最终会写到本地磁盘。每个map的输出先写入内存缓冲区,当写入的数据达到设定的阈值时,系统为输出操作启动的守护线程会将缓冲区的数据写入磁盘,这个过程称为spill。
在spill写入之前,会进行排序,首先按照partition进行排序,然后在每个partition中再按照key进行排序。partition和reduce是一对一的,后续reduce读取数据就会根据对应的partition读取相应的数据。
当所有spill写完之后,会进入spill文件的combiner过程,这个过程相当于本地的一次reduce操作,因为map任务如果输出量很大,就会进行多次spill,那就会产生多个文件,combiner过程会简单的合并重复的key值,避免map端最终生成的中间文件拥有重复的key。
combiner过程一般可以直接调用reduce方法。
至此,map端的shuffle过程结束。
reduce端
在reduce端的shuffle过程是copy和merge-sort。
reduce任务从各个map任务拖取它所需要的数据的过程就是copy,拖过来的数据都是经过排序的,所有最后的计算就是将来自不同map的数据进行归并排序(merge-sort)。一边copy一边排序,最终生成一个较大的文件作为reduce的输入。
这样,reduce端的shuffle过程结束。
reduce阶段
reduce阶段主要是将输入的数据输出到HDFS中,也就是将计算结果写入HDFS中。