MapReduce各个执行阶段
(1)MapReduce框架使用InputFormat模块做Map前的预处理,比如验证输入的格式是否符合输入定义;然后,将输入文件切分为逻辑上的多个InputSplit,InputSplit是MapReduce对文件进行处理和运算的输入单位,只是一个逻辑概念,每个InputSplit并没有对文件进行实际切割,只是记录了要处理的数据的位置和长度。
(2)因为InputSplit是逻辑切分而非物理切分,所以还需通过RecordReader根据InputSplit中的信息来处理InputSplit中的具体记录,加载数据并转换为适合Map任务读取的键值对,输入给Map任务。
(3)Map任务会根据用户自定义的映射规则,输出一系列的<key,value>
作为中间结果。
(4)为了让Reduce可以并行处理Map的结果,需要对Map的输出进行一定的分区(partition)、排序(sort)、合并(combine)、归并(merge)等操作,得到<key,value>
形式的中间结果,再交给对应的Reduce进行处理,这个过程称为shuffle
。从无序的<key,value>
到有序的<key,value-list>
,这个过程用Shuffle来称呼是非常形象的。
(5)Reduce以一系列<key,value-list>
中间结果为输入,执行用户定义的逻辑,输出结果给OutputFormat模块。
(6)OutpFormat模块会验证输出目录是否已经存在以及输出结果类型是否符合配置文件中的配置类型,如果都满足,就输出Reduce的结果到分布式文件系统。
摘自《大数据技术原理与应用》
Shuffle过程详解
Shuffle过程是MapReduce整个工作流程的核心环节,理解Shuffle过程的基本原理,对于理解MapReduce流程至关重要。
Shuffle过程简介
所谓Shuffle,是指对Map输出结果进行分区、排序、合并等处理并交给Reduce的过程。因此,Shuffle过程分为Map端的操作和Reduce端的操作。
(1)在Map端的Shuffle
Map的输出结果首先被写入缓存,当缓存满时,就启动溢写操作,把缓存中的数据写入磁盘文件并清空缓存。当启动溢写操作时,首先需要把缓存中的数据进行分区,然后对每个分区的数据进行排序和合并,之后再写入磁盘文件。每次溢写操作会生成一个新的磁盘文件,随着Map任务的执行,磁盘中就会生成多个溢写文件。在Map任务全部结束之前,这些溢写文件会被归并成一个大的磁盘文件,然后通知相应的Reduce任务来领取属于自己处理的数据。
(2)在Reduce端的Shuffle过程
Reduce任务从Map端的不同Map机器领回属于自己处理的那部分数据,然后对数据进行归并后交给Reduce处理。
Map端的Shuffle过程
1、数据分片
2、运算结果写入缓存
3、缓存达到阈值,溢写到磁盘文件
溢写前会进行分区,分区内排序和合并(可选)
4、归并成大文件
每次溢写会生成一个溢写文件,这些溢写文件最终需要被归并成一个大文件。
归并的意思:生成key和对应的value-list。
文件归并时,如果溢写文件数量超过参数min.num.spills.for.combine的值(默认为3)时,可以再次进行合并
- 每个Map任务分配一个缓存
- MapReduce默认100MB缓存
- 设置溢写比例0.8
- 分区默认采用哈希函数
- 排序是默认的操作
- 排序后可以合并(Combine)
- 合并不能改变最终结果
- 在Map任务全部结束之前进行归并
- 归并得到一个大的文件,放在本地磁盘
- 文件归并时,如果溢写文件数量大于预定值(默认是3)则可以再次启动Combiner,少于3不需要
合并(Combine)和归并(Merge)的区别:
两个键值对<“a”,1>
和<“a”,1>
,如果合并,会得到<“a”,2>
,如果归并,会得到<“a”,<1,1>>
Reduce端的Shuffle过程
1、领取数据
2、归并数据
3、数据输入给Reduce任务
- Reduce任务通过RPC向JobTracker询问Map任务是否已经完成,若完成,则领取数据
- Reduce领取数据先放入缓存,来自不同Map机器,先归并,再合并,写入磁盘 多个溢写文件归并成一个或多个大文件,文件中的键值对是排序的
- 当数据很少时,不需要溢写到磁盘,直接在缓存中归并,然后输出给Reduce