大数据计算框架——MapReduce(内含详细的shuffle过程)

1. MapReduce模型简介

MapReduce同样是谷歌公司的MapReduce的开源实现,其要比谷歌的MapReduce的使用门槛低很多。MapReduce将复杂的、运行于大规模集群上的并行计算过程高度地抽象到两个函数:Map和Reduce函数。

主要思想:“分而治之”+计算向数据靠拢。一个存储在分布式文件系统中的大规模数据集,在处理之前将会被切分成为许多独立的小数据块,这小小的数据块会被多个Map任务并行处理。MapReduce框架会为每个Map任务输入一个数据集,Map任务的结果会继续作为Reduce任务的输入,最终由Reduce任务输出最后的结果,并写入分布式文件系统。前提条件:待处理的数据可以分解成为许多的小的数据集,而且每个小的数据集可以并行的进行处理。

计算向数据靠拢:在一个集群中,只要有可能,MapReduce框架就会将Map程序就近地在HDFS数据所在的数据节点运行,即将计算节点和存储节点在一起运行。

2. Map 和 Reduce 函数

二者是Hadoop模型的核心,二者是由程序员开发者负责具体实现的。程序员只需要关注这两个函数如何编写,而不需要处理并行编程中的其他各种复杂的问题,如分布式存储、工作调度等都会由MapReduce框架进行处理。

2.1 Map函数

输入来源于分布式文件系统的文件块,这些文件块的格式是任意的,可以是文档,也可以是二进制格式的。文件块是一系列元素的集合,这些元素的类型也是任意的。Map函数将输入的元素转换为 <key,value>形式的键值对,键和值的类型也是任意的,但其中的键值不作为标志性属性,没有唯一性,不同的键值对的key值可以相同,一个Map函数可以生成多个具有相同key值的<key,value>对。

2.2 Reduce函数

其输入为Map函数的结果,<key,List(value)>对,这种类型的键值对所代表的意思是List(value)是一批同属于同一个key值的value。

Reduce函数将一些列具有相同的键值的键值对以某种方式组合起来,输出处理后的键值对,输出的结果为一个文件。用户可以指定Reduce函数的个数。

2.3 两个函数的关系图

在这里插入图片描述

3. MapReduce工作流程

3.1 工作流程概述(注意两点)

MapReduce的输入和输出都需要依赖于分布式文件系统,输入的数据块来源于分布式文件系统,输出存储与分布式文件系统的不同的节点上。

流程:一个大的MapReduce作业:

(1)首先会被拆分成许多个Map任务在多台机器上并行执行,每个Map任务通常运行在数据存储的节点上,这样计算就向数据靠拢。
(2)当Map任务运行结束后,生成许多<key,value>这样的中间结果。
(3)这些中间结果会被分发到多个Reduce任务在多台机器上并行执行,具有相同key值的<key,value>对将会被发送给同一个Reduce进行处理。
(4)最终将结果保存至分布式文件系统中,进行输出。

注意:不同的Map人物之间不会进行通信,不同的Reduce任务之间也不会进行通信。

Map任务的中间结果保存在本地的内存之中。

3.2 工作流程图片说明

在这里插入图片描述

4. MapReduce执行的各个阶段

4.1 自己总结的画的文字配图(共6个阶段)

有什么不理解的地方可以评论私聊。
在这里插入图片描述

5. Shffle过程详解

Shuffle过程是整个MapReduce工作流程的核心,理解其过程的基本原理,对于理解MapReduce的真个流程来说至关重要。

5.1 Shuffle过程简介

所谓shuffle,是指对Map输出结果进行分区,排序,合并,等处理并交给Reduce的过程,分为Map端的shuffle和Reduce端的shuffle。

5.1.1 shuffle过程图

在这里插入图片描述

5.1.2 shuffle过程讲解

  1. Map端的shuffle。
    (1)Map的输出结果首先会被写入缓存当中。
    (2)当缓存满时,便会启动溢写操作(这里的缓存满并不是缓存真的满了,而是达到了一定的溢写比,比如设置当缓存的实用程度达到了80%,便启动了溢写操作,剩下的20%的内存接着来存放数据),把缓存中的数据写入磁盘当中,并清空缓存。
    (3)当启动溢写操作的时候,先将缓存中的数据进行分区,然后对每个分区的数据进行排序,合并,之后再写入磁盘文件。
    (4)每次溢写便会生成一个新的磁盘文件,Map任务数量的增多,磁盘文件的数量也会跟着增多,最后这些磁盘文件将会被归并为一个大的磁盘文件。
  2. Reduce端的shuffle
    Reduce任务从Map端的不同Map机器领回属于自己的处理的数据,然后对数据进行归并,后交给Reduce处理。

5.2 Map端的Shffle过程

(1)输入数据和执行Map任务。

输入的数据一般是从分布式文件系统中而来的,一般是以文件块的形式,文件块的格式时任意的,可以是文档,也可以是二进制。Map任务接受<key,value>作为输入后,按照一定的规则映射为一批<key,value>进行输出。

(2)写入缓存。

每个Map任务都会被分配一个缓存,Map的输出结果不是立即写入磁盘,而是首先写入缓存当中。在缓存中积累了一定数量的Map输出结果后,再一次批量性的写入磁盘,这样可以大大减少对磁盘的I/O影响。注意:在写入缓存之前,key与value值都会被序列化为字节数组。

(3)溢写(分区,排序,合并(归并))。

MapReduce的缓存容量是有限的,默认大小是100MB。随着Map任务的执行,缓存中的Map结果的数量会不断的增加,当达到一定的溢写比时,就必须启动溢写操作,把缓存中的内容一次性的写入磁盘中,并清空缓存。溢写的过程通常是由另一个单独的后台线程来完成的,不会影响Map结果往缓存中写入。

在溢写到磁盘之前,缓存中的数据首先会被分区。缓存中的数据是<key,value>形式的键值对。MapReduce通过Partitioner接口对这些键值对进行分区,默认采用的分区方式是Hash函数对key进行哈希后再用Reduce任务的数量进行取模,这样,就可以把map输出结果均匀地分配给等量的Reduce任务去并行处理了。当然,MapReduce也允许用户通过重载Partitioner接口来自定义分区方式。

对于每个分区内的所有键值,后台线程会根据值对他们进行排序,排序是MapReduce的默认操作。排序后根据用户是否定义函数Combiner来选择是否执合并函数,如有定义则执行,如没有则不执行。

(4)文件归并。

每次溢写都会生成一个新的溢写文件在磁盘中,随着MapReduce的执行,溢写文件会越来越多,最终,在Map任务全部结束之前,系统会对所有溢写文件中的数据进行归并为一个大文件,生成一个大的溢写文件,这个大的溢写文件中的左右的键值对也是经过分区和排序的。

5.2.1 合并操作(补充)

所谓合并,就是将那些具有相同key的<key,value>的value加起来,比如:<a,1><a,2>合并为<a,2>

5.2.2 归并操作(补充)

所谓归并,就是讲那些具有相同key的键值对会被归并成一个新的键值对。比如:<a,1><a,2>归并为<a,<1,2>>

5.3 Reduce端的shuffle

只需要从Map端读取Map结果,然后执行归并操作,最后输送给Reduce任务进行处理。

(1)“领取数据”。

Map端的Shuffle过程结束后,所有Map输出结果都保存在Map端的本地磁盘当中,所以Reduce任务首先要把这些数据请求拉回本地磁盘上。

(3)归并数据。

从Map端领取回来的数据首先会被保存在Reduce本地的缓存当中,如果缓存满,就会像Map端一样被溢写到磁盘当中。系统中一般存在多个Map机器,Reduce任务会从多个Map机器领回属于自己处理的那些分区的数据。当溢写操作启动的时候,具有相同key值的键值对会被执行归并操作,如用户定义合并函数,则也会执行合并操作。溢写文件的增多,最终也会归并为一个大的磁盘文件,归并的时候还会给键值对进行排序。

(4)把数据输入给Reduce任务。

将大的排序,归并(合并)好的大的磁盘文件输入给Reduce任务,Reduce任务会执行Reduce函数中定义的各种映射,输出最终的结果,并保存到分布式文件系统当中。

猜你喜欢

转载自blog.csdn.net/zc666ying/article/details/106357175