MapReduce过程详解

在描述具体过程之前,先上一幅大图。

MapTask的工作流程

Map Task在工作时,使用FileInputFormat组件读取输入文件(默认使用TextInputFormat),把数据变成<key,value>,写新的InputFormat即可处理不同的数据(图片、视频、数据库中的记录等)。一次读一行是TextInputFormat的特性,并不代表就只能这么读。但是无论怎么读,必须返回<key,value>

在收到读入的<key,value>后,map task会把<key,value>交给我们自定义的Mapper。Mapper将结果write出来之后,会进入到OutputCollector里面。这个OutputCollector是不能自定义的,完全是Map Task内部的组件。OutputCollector会把数据写入到环形缓冲区里面,是一个数组。

当数据写入环形缓冲区(默认大小100M,可用空间大约为80%,剩余空间用于排序等)后,有spiller组件将数据从缓存中读出,调用Partitioner进行分区,并排序,然后写入到文件中。这个文件位于Map Task工作目录下面。环形缓冲区每溢出一次就产生一个文件。文件分区且区内有序。最终所有数据读取完毕后,将内存中的数据也溢出。

接下来会进行merge操作,将刚刚生成的文件进行合并。过程中使用归并排序算法。最终生成一个大文件,大文件中的内容也是分区且区内有序的。这是Map Task的最终结果文件。

ReduceTask的工作流程

每一个MapTask都会生成一个大文件。

每一个ReduceTask都有一个编号,每一个分区也有一个编号。每个ReduceTask负责处理自己的分区。

在合适的时间,ReduceTask会去MapTask的机器下载自己分区的数据,放到自己的工作目录下面。接下来要对这些文件进行合并(归并排序),以保证最终结果的有序。

这里有一个问题,ReduceTask如何处理拿到的合并文件?

我们自己写的Reducer组件里面有一个reduce方法,参数为<key,list<values>>。对每个不同的key,调用一次reduce方法。

这里有一个组件GroupingComparator来判断哪些对象是相同的,并把相同的对象(key相同)分为一组。

reduce方法写出结果后,ReduceTask会调用OutputFormat组件把结果输出到文件中。

每个ReduceTask把结果输出到自己的文件中。

所谓的Shuffle过程指的是从Mapper写出来到Reducer调用之前的过程。包含了一系列数据传输以及分组排序的过程。

这里还缺失一个Combine的过程。

Combine过程

Combine用于在Mapper写出过程后,提交给Reducer之前,先对Mapper输出的数据进行合并,可以提高后续reduce过程的效率。具体的调用时机是spiller在溢出时调用Combiner进行合并。然后在各个文件merge到大文件,生成MapTask的唯一输出的过程中,也会调用Combiner。

一般来说Combiner的工作逻辑与Reducer的工作逻辑相同。

Combiner使用注意

使用Combiner必须保证输出不能影响最后的结果。有些时候Combiner也是不能用的。比如在算随机数的时候。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值