MapReduce运行原理详解

 

 

1、MapReduce简介

 

定义:MapReduce是一个用于处理海量数据的分布式计算框架。

 

特点:数据分布式存储(HDFS)、作业调度(任务分配、进出规则)、容错(故障处理)、机器间通信(服务器通信协调)等。

 

举个简单的例子:比如说有一堆钞票,面值大小为10 50 100,103个人来统计各种面值的数量?首先这堆钞票均分给100个人,每个人统计出各种面值的数量,这为Map阶段。然后3个人分别汇总一种面值的数量之和,此为Reduce阶段。

 

关键思想:分而治之、近计算原则(处理最近的数据)、移动计算原则(计算移动,数据不移动)

 

2、MapReduce计算框架(执行流程)

 

流程示意图:

 

image

 

2.1 Map端流程分析

 

1.对于输入文件,会进行分片,对于一个split,有一个map任务进行处理。每个Map在内存中都有一个缓存区,map的输出结果会先放到这个缓冲区中。在缓冲区中,会进行预排序。

2.缓冲区默认大小是100MB(可以通过io.sort.mb属性更改大小),当缓冲区中的数据达到特定的阈值时,系统会启动一个后台线程把缓冲区的内容spill(溢写)到磁盘。溢出到磁盘的一个临时文件中,即80%的内容成为一个临时文件。当这80%的内容溢出时,map会继续向剩余的20%缓冲区中输出。

3.Spill线程在把缓冲区中的数据写到磁盘前,会进行一个二次快速排序,首先根据数据所属的Partition排序,然后每个Partition中再按Key排序。输出包括一个索引文件和数据文件。如果设定了Combiner,将在排序输出的基础上进行。

4.Comibner就是一个Mini Reducer,在执行Map任务的节点本身运行,对Map的输出做一次简单Reduce,使得Map的输出更紧凑,更少的数据会被写入磁盘和传送到Reduce端。

5.一个Map任务会产生多个spill文件,在Map任务完成前,所有的spill文件将会归并排序为一个索引文件和数据文件。当spill文件归并完成后,Map将删除所有的临时文件,并告知TaskTracker任务已完成。

6.对写入到磁盘的数据可以选择采取压缩的方式,如果需要压缩,则需要设置mapred.compress.map.output为true。

7.还有一个Partition的概念,一个临时文件是进行了分区的,并且分区的数量由reduce的数量决定,不同的分区传给不同的reduce。

 

2.2 Reduce端流程分析:

 

1.Reduce端通过HTTP获取Map端的数据,只要有一个map任务完成,Reduce任务就开始复制它的输出,这称为copy阶段。

2.JobTracker知道Map输出与TaskTracker的映射关系,Reduce端有一个线程间歇地向JobTracker询问Map输出的地址,直到把所有的数据都获取到。

3.如果map输出比较小,他们被复制到Reduce的内存中,如果缓冲区空间不足,会被复制到磁盘上。复制的数据放在磁盘上,后台线程会进行归并为更大的排序文件。对于压缩文件,系统会自动解压到内存方便归并。

4.当所有的Map输出被复制后,Reduce任务进入排序阶段(确切的说是归并阶段),这个过程会重复多次。Merge有三种形式:内存到内存,内存到磁盘,磁盘到磁盘。

5.内存到内存默认不启用;内存到磁盘的方式也会产生溢写,如果设置了Combiner,此时也会启用,在磁盘上生成多个溢写文件;磁盘到磁盘会生成一个最终的文件作为Reduce的输入。

 

3、MapReduce实现步骤

 

步骤示意图:

 

image

 

(1)在客户端启动任务,客户端向JobTracker请求一个Job ID。

(2)将运行任务所需要的程序文件复制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客户端计算所得的输入划分信息。这些文件都存放在JobTracker专门为该任务创建的文件夹中。文件夹名Job ID。

(3)JobTracker接收到任务后,将其放在一个队列里,等待调度器对其进行调度,当作业调度器根据自己的调度算法调度到该任务时,会根据输入划分信息创建N个map任务,并将map任务分配给N个TaskTracker(DataNode)执行。

(4)map任务不是随随便便地分配给某个TaskTracker的,这里有个概念叫:数据本地化(Data-Local)。意思是:将map任务分配给含有该map处理的数据块的TaskTracker上,同时将程序JAR包复制到该TaskTracker上来运行,这叫“运算移动,数据不移动”。而分配reduce任务时并不考虑数据本地化。

(5)TaskTracker每隔一段时间会给JobTracker发送一个Heartbeat(心跳),告诉JobTracker它依然在运行,同时心跳中还携带着很多的信息。比如当前map任务完成的进度等信息。当JobTracker收到作业的最后一个任务完成信息时,便把该作业设置成“成功”。当JobClient查询状态时,它将得知任务已完成,便显示一条消息给用户。

 

4、总结

 

虽然MapReduce这个组件很优秀,但是它本身也有很多痛点让工程师很苦恼。比如单点故障、JobTracker任务繁重、taskTracker容易出现OOM和资源浪费等。进入了Hadoop2.X时代之后,引入了一个组件Yarn,然后MapReduce框架也具有了更好的扩展性、可用性、可靠性、向后兼容性和更高的资源利用率。

posted @ 2019-12-31 18:03  雨中漫步人生  阅读(639)  评论(0编辑  收藏  举报