MapRuduce中shuffle过程简介

MapReduce的核心在于shuffle过程,包括Map端和Reduce端的shuffle。Map端首先将数据写入缓存,当缓存满时溢写到磁盘,进行分区、排序和合并。Reduce端领取数据后,归并数据并输入到Reduce任务中进行处理。整个shuffle过程中,分区、排序和合并操作确保了数据的正确流向。

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

shuffle过程是MapReduce整个工作流程的核心环节

map : mapShuffle
reduce: reduceShuffle
**1.在Map端的shuffle过程:Map输出的结果首先被写入缓存,当缓存满时,启动溢写(环形缓冲区(100M。80M))操作,把缓存写入磁盘文件,然后清空缓存,
2当启动溢写操作时,首先需要把缓存中的数据进行分区(partition),然后对每个分区进行排序(sort),合并(combine),
3之后再写入磁盘文件,每次溢写操作会生成一个新的磁盘文件,随着Map任务的执行,会有越来越多的磁盘文件,然后通知相应的Reduce来领取属于自己的数据
**2.在Reduce端的shuffle过程,Reduce任务领回属于自己的数据后,然后对数据进行归并(Merge)然后交给Reduce处理
2.Map端的shuffle
**Map端的shuffle包括四个步骤

  1. 输入数据和执行Map任务:Map输入的数据一般保存在HDFS文件块中,这些文件块的格式可以是任意的
  2. 写入缓存:每个Map任务都会被分配一个缓存,Map输出的结果不是立即写入磁盘,而是首先写入缓存,积累一定缓存后,再一次性批量写入磁盘,这样可以大大减少对磁盘IO的影响,因为每次磁盘寻址开销很大,在写入缓存之前,键值对都会被序列化成字节数组
  3. 溢写(分区,排序,合并):提供给MapReduce的缓存容量是有限的,默认大小100MB,随着Map任务的执行,缓存会越来越多,这时就必须启动溢写操作(spill),溢写过程通常是由另一个单独的后台线程来完成,但是为了保证Map任务写入缓存不受溢写影响,一般设置一个溢写比例0.8,在溢写到磁盘之前,缓存中的数据首先会被分区(partition)(),MapReduce通过Partitioner接口对这些键值对进行分区,采用默认的分区方式是Hash函数对key进行哈希后再用Reduce任务的数量进行取模,这样就可以把Map输出结果均匀的分配给所有的Reduce去并行处理,当然也可以自定义分区机制,对于分区内的每个键值对,后台线程会根据key对他们进行排序(sort),排序是MapReduce的默认操作,排序结束后还包含一个可选的合并(combine)操作,如果用户事先没有定义combiner函数,就不用进行合并,如果定义了,这个操作会减少需要溢写到磁盘的数据量,合并就是把相同key的value加起来,减少键值对的数量,功能与Reduce相似,但是并不是所有的场合都可以使用combiner,因为combiner的输出是Reduce的输入,combiner绝不能改变Reduce的计算结果,一般在累加,最大值的这种场景使用,每次溢写操作都会生成一个新的溢写文件,所有写入这个文件中的数据都是经过分区和排序的。
  4. 文件归并:在Map任务结束之前,系统会对所有的溢写文件进行归并(Merge),生成一个大的溢写文件,归并就是对具有相同key的键值对合并,形成一个新的键值对,另外,在文件归并时,如果磁盘中生成溢写文件的数量超过min.num.spills.for.combine的值时(默认是3,用户可以修改),那么就可以再次运行combiner对数据进行合并操作,从而减小写入磁盘的数据量
    ****经过上述四个步骤后,Map端的shuffle过程全部完成,最终生成的大文件会被存放在本地磁盘中,这个大文件中的数据是被分区的,不同的分区分发到不同的Reduce任务进行并行处理,JobTracker会一直监测Map任务的执行,当监测到一个Map任务完成后,就会立刻通知相关的Reduce任务来领取数据,开始Reduce端的shuffle过程。
    3.Reduce端的shuffle
    **Reduce端的shuffle包括三个步骤:
  5. 领取数据:Map端的shuffle过程结束后,结果会保存在本地磁盘中,Reduce任务只需要把这些数据领取(Fetch)回来存放到自己机器所在的磁盘上,因此,每个Reduce任务在执行之前,大部分时间都在领数据,每一个Reduce会不断通过RPC向JobTracker询问Map任务是否已经完成
  6. 归并数据:领回数据后,会首先被存在Reduce任务所在机器的缓存中,如果缓存满了,就会像Map一样发生溢写操作,由于在shuffle阶段,真正的Reduce还没有执行,这时可以把内存的大部分空间分配给shuffle过程作为缓存,缓存中的数据是来自不同机器的,一般会存在很多可以合并(combine)的键值对,当溢写程序启动时,具有相同key的键值对会被归并,如果用户定义了combiner,则归并后还可以执行combiner,减少写入磁盘的数据量,每个溢写过程结束后,都会在磁盘生成一个溢写文件,当溢写文件过多时也会像Map一样被归并成一个大文件,归并是也会进行排序,当数据很少时,写入缓存就行,不需要溢写到磁盘,而是直接在内存中执行归并操作,直接输出给Reduce任务,需要说明,把这些溢写文件归并成一个大文件需要多轮归并操作,每轮归并操作的文件数量有参数io.sort.factor来决定(默认是10,可以修改)
  7. 把数据输入Reduce任务:磁盘中经过多轮归并后得到若干个大文件,不会继续归并成一个新的大文件,而是直接输出给Reduce任务,这样可以减少磁盘的读写开销,这样整个shuffle过就结束了,接下来Reduce任务会执行Reduce函数中定义的各种映射,输出最终结果,并保存到分布式文件系统中。
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:
map task 从split中读取数据,进行处理后,输出key/value,对键值对进行Partitioner后,存入到缓存中,缓存默认大小是100M,当缓存内容达到80M时,启动溢写操作,把缓存区数据写入一个溢写文件,在写入文件之前,会对键值对进行分组,排序和合并(如果设置的话),当该map task处理完所有数据后,需要对该map生成的所有溢写文件进行merge操作,生成一个文件作为该maptask的成果,reduce task接受到通知后,就回拉取各个map task的成果数据,放到缓存区中,当缓存区内容达到阀值时,同样执行溢写操作,生成溢写文件,当把所有的map task的成果数据读取完毕后,会把生成的所有溢写文件进行merge操作,生成一个文件作为reduce task的输出数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值