【MapReduce分布式并行编程模型】

本文详细介绍了MapReduce模型的工作流程,重点剖析了Shuffle过程,包括Map端的分区、排序、合并和溢写,以及Reduce端的数据领取、归并和输出。通过理解Shuffle,读者能更好地掌握分布式并行编程的精髓。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


🚀🚀前言

在学习分布式并行编程模型MapReduce之前,我觉得了解产生背景是很有必要的:

在2005年前后,CPU领域的“摩尔定律”逐渐失效,为了提高程序的运行性能,人们就不能把过多的希望寄托在提升CPU性能上来,因此人们开始着眼于分布式并行编程模型来提高程序的性能,MapReduce就是由谷歌公司率先提出的分布式并行编程模型。
补充:传统的程序都是以单指令、单数据流的方式顺序执行,这虽然符合人们日常的思维逻辑,但是程序的性能受到了很大的限制。分布式并行程序可以运行由大量计算机构成的集群上,从而可以充分利用集群的并行计算的能力,同时通过向集群中增加新的计算节点就可以很容易的实现算力的扩充。


一、 🚀MapReduce是什么?

MapReduce是谷歌公司的核心的算力模型。拿作者的理解来说,MapRedece就是Map+Reduce。
MapReduce就是讲复杂的、运行于大规模集群上的并行计算过程高度的抽象到两个函数:Map和Reduce。

在这里插入图片描述

二、🚀MapReduce工作流程

MapReduce的工作流程图
在MapReduce的整个执行过程中,Map任务的输入文件 、Reduce任务的处理结果都是保存在分布式文件系统中的,而Map任务处理得到的中间结果则保存在本地存储中(如磁盘)。

注意:

  1. 只有当Map处理全部结束后,Reduce过程才能开始
  2. 只有Map需要考虑数据局部性,实现“计算向数据靠拢”,而Reduce则无需考虑数据局部性
  3. 不同的Map任务之间不会进行通信
  4. 不同的Reduce任务之间也不会发生任何信息交换
  5. 用户不能显式地从一台机器向另一台机器发送信息
  6. 所有的数据交换都是通过MapReduce框架自身去实现的

三、🚀Shuffle过程

🐒Shuffle简介

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

所谓Shuffle,是指对Map输出结果进行分区、排序、合并等处理并交给Reduce的过程。
因此,Shuffle 过程分为Map端的操作和 Reduce端的操作。
见下图:

Shuffle过程

(1)在Map 端的 Shuffle 过程
Map 的输出结果首先被写入缓存, 当缓存满 时,就启动溢写操作,把缓存中的数据写入磁盘文件,并清空缓存。当启动溢写操作时,首先需要把缓存中的数据进行分区,然后对每个分区的数据进行排序(Sort)和合并(Combine),之后再写入磁盘文件。每次溢写操作会生成一个新的磁盘文件,随着Map任务的执行,磁盘中就会生成多个溢写文件。在Map任务全部结束之前,这些溢写文件会被归并(Merge)成一个大的磁盘文件,然后通知相应的Reduce任务来领取属于自己处理的数据。

(2)在Reduce 端的 Shuffle 过程
Reduce 任务从 Map 端的不同Map机器领回属于自己处理的那部分数据,然后对数据进行归并(Mergge)后交给 Reduce 处理。

🐒Map端的Shuffle

Map端的Shuffle过程

✍输入数据和执行Map任务

Map任务的输入数据一般保存在分布式文件系统(如 GFS或HDFS)的文件块中,这些文件块的格式是任意的,可以是文档,也可以是二进制格式的。Map任务接受<key, value>作为输入后,按一定的映射规则转换成一批进行输出。

✍写入缓存

每个 Map任务都会被分配一个缓存,Map的的输出结果不是立即写入磁盘,而是首先写入缓存。在缓存中积累一定数量的Map输出结果以后,再一次性批量写入磁盘,这样可以大大减少对磁盘IO 的影响。
因为,磁盘包含机械部件,它是通过磁头移动和盘片的转动来寻址定位数据的,每次寻址的开销很大,如果每个Map输出结果都直接写人磁盘,会引入很多次寻址开销,而一次性批量写人,就只需要一次寻址、连续写入,大大降低了开销。
需要注意的是,在写人缓存之前, key与 value 值都会被序列化成字节数组。

✍溢写(分区、排序、合并)

缓存中的Map结果的数量不断增加,很快就会占满整个缓存,这是就必须启动溢写操作,把缓存中的内容一次性写入磁盘中,并且清空缓存。
在溢写到磁盘之前,缓存中的数据首先会被分区(Partition),数据以键值对的形式存放。
对于每个分区中的所有键值对,后台程序会根据键值对它们进行排序(Sort),排序是默认的操作。
排序结束后,还包括一个可选的合并(Combine)操作,注意合并的操作是可选的,而排序则是默认的。

*关于溢写、合并、以及下面将要提到的归并,作者会专门写一篇博客提供大家参考。

✍文件归并

每次溢写操作都会在磁盘中生成一个新的溢写文件,随着MapReduce任务的进行,磁盘中的溢写文件数量会越来越多。当然,如果Map输出结果果很少,磁盘上只会存在一个溢写文件,但是通常都会存在多个溢写文件。最终,在Map任务全部结束之前,系统会对所有溢写文件中的数据进行归并(Merge),生成一个大的溢写文件,这个大的溢写文件中的所有键值对也是经过分区和排序的。

另外,进行文件归并时,如果磁盘中已经生成的溢写文件的数量超过参数min.num.spills.for.combine的值时(默认值是3,用户可以修改这个值),那么,就可以再次运行Combiner,对数据进行合并操作,从而减少写入磁盘的数据量。但是,如果磁盘中只有一两个溢写文件时,执行合并操作就会“得不偿失”,因为执行合并操作本身也需要代价,因此不会运行 Combiner。

✍小结

经过上述4个步骤以后,Map 端的 Shuffle 过程全部完成,最终生成的一个大文件会被存放在本地磁盘上。这个大文件中的数据是被分区的,不同的分区会被发送到不同的Reduce任务进行并行处理。JobTracker会一直监测 Map任务的执行, 当监测到一个Map任务完成后,就会立即通知相关的Reduce任务来“领取”数据,然后开始R educe 端的 Shuffle 过程。

🐒Reduce端的Shuffle过程

Reduce端的Shuffle过程

✍ “领取”数据

Map 端的 Shuffle过程结束后,所有Map输出结果都保存在Map机器的本地磁盘上,Reduce任务需要把这些数据“领取”(Fetch )回来存放到自己所在机器的本地磁盘上。因此,在每个Reduce任务真正开始之前,它大部分时间都在从Map端把属于自己处理的那些分区的数据“领取”过来。
每个Reduce任务会不断地通过RPC向JobTracker询问 Map任务是否已经完成;JobTracker监测到一个Map任务完成后,就会通知相关的Reduce任务来“领取”数据;一旦一个 Reduce任务收到JobTracker 的通知,它就会到该Map任务所在机器上把属于自己处理的分区数据领取到本地磁盘中。一般系统中会存在多个Map机器,因此Reduce任务会使用多个线程同时从多个Map机器领回数据。

✍归并数据

从Map端领回的数据会首先被存放在Reduce任务所在机器的缓存中,如果缓存被占满,就会像Map端一样被溢写到磁盘中。由于在Shuffle 阶段Reduce任务还没有真正开始执行,因此,这时可以把内存的大部分空间分配给Shuffle过程作为缓存。
需要注意的是,系统中一般存在多个 Map机器,Reduce任务会从多个Map机器领回属于自己处理的那些分区的数据,因此缓存中的数据是来自不同的Map机器的,一般会存在很多可以合并(Combine)的键值对。
当溢写过程启动时,具有相同key的键值对会被归并(Merge),如果用户定义了Combiner,则归并后的数据还可以执行合并操作,减少写入磁盘的数据量。每个溢写过程结束后,都会在磁盘中生成一个溢写文件,因此磁盘上会存在多个溢写文件。
最终,当所有的 Map端数据都已经被领回时,和Map端类似,多个溢写文件会被归并成一个大文件,归并的时候还会对键值对进行排序,从而使得最终大文件中的键值对都是有序的。当然,在数据很少的情形下,缓存可以存储所有数据,就不需要把数据溢写到磁盘,而是直接在内存中执行归并操作 然后直接输出给Reduce任务。
需要说明的是,把磁盘上的多个溢写文件归并成一个大文件可能需要执行多轮归并操作。每轮归并操作可以归并的文件数量是由参数io.sort.factor的值来控制的 默认值是 可以修改)。假设磁盘中生成了50个溢写文件,每轮可以归并10个溢写文件,则需要经过5轮归并,得到5个归并后的大文件。

✍把数据输出给Reduce任务

磁盘中经过多轮归并后得到的若干个大文件,不会继续归并成一个新的大文件,而是直接输人给 Reduce任务,这样可以减少磁盘读写开销。由此整个 Shuffle 过程顺利结束。接下来,Reduce任务会执行 Reduce函数中定义的各种映射,输出最终结果,并保存到分布式文件系统中(比如 GES或HDFS)。

总结

🚀🚀🚀以上就是作者对MapReduce相关知识点的大概总结,希望对读者能有所帮助!!
内容不全面,也可能存在错误,如发现有误欢迎私信纠正,不尽感激。
💕💕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Duang~Lucky.Mr.Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值