鱼喃

听!布鲁布鲁,大鱼又在那叨叨了

Apache Hadoop(4)---MapReduce框架背后的事情

MapReduce看起来是如此简单,可背后又是如何运转的呢?

MapReduce作为Hadoop的编程框架,把数据的操作抽象成map和reduce操作,简化了大数据编程的复杂度,但是MapReduce是如何执行的呢?

对于每一个MapReduce,都对应着一个map,一个reduce(可能没有),以及一个job描述,当提交这个任务时,Hadoop框架会解析这个job,然后按照描述来启动mapper、reducer,并且将输入文件灌入mapper,同时接收mapper输出,处理之后再喂给reducer,对reducer的结果处理之后就得到了最终结果。

a9163950472d3f8198c1769bb9ed8182.md.png

Mapper

默认情况下,对于HDFS数据文件的每一个block,Hadoop都会启动一个mapper,也就是说一个mapper负责处理一个block,这样在资源充足的情况下能大大加快处理速度。HDFS的文件格式有很多,当它是默认的文本格式时,框架会读取这个block并且循环调用mapper的map方法,每次喂入一行,KV键值对分别是偏移量和文本内容。

对于接收到的内容,mapper在处理之后通过context输出新的若干键值对,框架会接收这些键值对。为了减少磁盘读写,这些输出首先被存储在缓冲区中,当缓冲区达到一定阈值之后开始将缓冲区内容写入到磁盘中。对于这些内容,首先按照后续处理的reducer不同划分成一个个小的分片(根据哈希等策略),然后针对每一个分片做一个内存内排序,如果MapReduce指定了combiner,再在分片上做一次combine操作,然后将结果合并后按照round-robin策略写入到不同的磁盘中,当mapper处理完所有数据后,再次合并所有的小文件,形成一个大的有序且分区的大文件。如果小文件的数量超过一定阈值,会在新的文件上再做一次combine操作,进一步减少文件大小,减少后续reducer的复制通信量以及加快硬盘读写。

Reducer

默认情况下,每个MapReduce只有一个reducer,但是可以根据需求,设置多个reducer。在每个reducer启动初期,会去每一个机器(application manager存放着所有该任务中的mapper和机器)上通过http协议拉取属于自己的那份数据,然后对于所有的有序文件集做排序和合并操作,形成一个新的大文件。需要注意的是,如果文件大小较少,则会直接进行内存内排序跟合并,而不会落盘。同样,如果文件数很多,会多次执行combine操作。

3012fedaef0c750464fcb02803582b20.md.png

e03256d63c64015fab76a35a0a86d3e5.md.png

然后框架按照键组织所有的键值对,每次喂入一个键以及所有的值,当reducer处理并生成新的键值对后,对结果做排序操作,然后写入HDFS相应目录。

当所有的reducer执行完毕之后,做收尾工作,删除mapper和reducer节点上生成的中间数据并释放资源。

由于不同机器性能不同等原因,不同的mapper结束时间不同,为了加快处理速度,reducer不会等到所有mapper处理完毕之后才开始启动,而是当一定比例的mapper执行结束后提前启动,然后拉取数据合并,这样等剩下的mapper结束之后能尽快的拉取剩下的数据,开始reduce操作。

容错

大数据中,一个必须要考虑的因素就是容错,在MapReduce中,如果一个mapper在执行时出现故障,只需要重新处理相应的block即可;可如果reducer出错,它就需要重新拉取相应mapper的结果,为了避免这种情况下带来的大量mapper重新处理,mapper的处理结果会等到整个任务完成之后才统一删除。