hadoop-深入理解MapReduce(二)-MapTask与ReduceTask

1.MapTask

1.1机制流程图

接着上一篇的job提交流程来继续分析画图

1.2源码分析

从一个应用程序的map中context.write开始

 继续进入mapContext.write

 继续进入output.write

 这里找到了collector.collect,与上面流程图对应,然后其中还包含getPartition通过分区器以分区的形式收集数据到环形缓冲区。

继续进入collect函数

我们可以发现我们存储的数据结构是一部分是元数据,一部分是实际数据,其中元数据中有index,partition,keystart,valstart。

 

 

也就是说结构大致如下

当数据超过缓冲区80%或者读完时会发生溢写,比如数据读完时就走完了mapper.run方法,那么后面继续走,我们观察output.close方法

 看到flush函数,很明显就是把数据刷出到磁盘。

 在flush函数中发现一个非常重要的函数sortAndSpill,即排序和溢写,和上面画的流程图符合。

 进入sortAndSpill后,找到sort函数,继续进入 

这时候进入了QuickSort类,已经暗示这么明显了,就是快排,但是我们还是继续深入,知道看到实现代码为止

 这个逻辑代码,大致看一下就知道是快排的逻辑了

排完序就准备溢写了,遍历每个分区进行溢写,输出到溢写文件split.out中

 sortAndSpill执行完后就到了merge阶段了,其中重点关注mergeParts函数

 遍历溢写文件 

 如果只有一个溢写文件,那么其就是最终输出文件

 归并完成后,同时会产生一个.index文件,用于索引实际内容,方便reduce拉取数据。

最后随着收集器关闭close,MapTask就基本结束了 

2.ReduceTask

2.1机制流程图

2.2源码分析

首先从ReduceTask源码中的run方法开始,这个源码一点都不含蓄,很直白啊,直接把三个阶段copy、sort、reduce写出来了。

 首先关注这个初始化函数initialize 

其中使用新的api然后outputFormat默认是TextOutputFormat,其他的一些基本参数初始化就直接略过 

initialize函数之后,又出现了一个init函数,我们进去看看初始化了哪些重要内容?

着重看new的实现类ShuffleSchedulerImpl

很明显需要获取MapTask的个数。

继续关注函数createMergeManager

 这个函数里也new了一个实现类MergeManagerImpl

 由于流程图中也提到了拉取数据一部分存在磁盘中一部分存在内存中,这里初始化的时候提前准备好了磁盘和内存

分析完其init方法后,进入run方法

 准备工作做完,ReduceTask开始从MapTask抓取数据。

 抓取完毕

copy阶段结束,状态切为sort

 后面进行归并排序

sort阶段结束,状态切换为reduce

 使用新的api,进入runNewReducer函数

 重点关注runNewReducer函数中的run函数

 这个就是我们通常编写reduce继承的Reducer类中的run方法,其中又调用了reduce方法,就是我们程序自己重写的业务方法

 我们自己编写的reduce方法里面肯定有context.write方法,进入

继续进入write函数  

 在进入real.write函数,我们发现先写key再写value

进入writeObject函数

很明显发现如果是Text就是字符串正常输出,如果不是,比如是自定义对象,那么就调用我们自定义对象时重写的toString方法来输出,到这里一个key就算输出完成了,后面基本就是多个key重复逻辑以及多个reduceTask那也是重复这些逻辑。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值