标签:
转自:http://www.open-open.com/lib/view/open1453097241308.html
MRAppMaster
MapReduce Job的时间线
MapReduce Job 运行的时间线:
reduce可能会在map阶段结束之前开始执行,因此上面显示的有重叠的地方。
现在我们集中考察map相,一个关键的问题是一个应用需要多少map任务去运行现在的这个job
我们退回到之前的一步,当一个用户提交一个应用的时候,若干信息被提供给了YARN ,分别是:
The number of files inside the input directory is used for deciding the number of Map Tasks of a job.
那么,输入的目录中文件的数量决定多少个map会被运行起来
应用针对每一个分片运行一个map,一般而言,对于每一个输入的文件会有一个map split。如果输入文件太大,超过了hdfs块的大小(64M)那么对于同一个输入文件我们会有多余2个的map运行起来。下面是FileInputFormat class 的getSplits()的伪代码:
num_splits = 0 for each input file f: remaining = f.length while remaining / split_size > split_slope: num_splits += 1 remaining -= split_size
where:
split_slope = 1.1 分割斜率 split_size =~ dfs.blocksize 分割大小约等于hdfs块大小
在mapreduce2.0以上版本mapreduce.job.maps
属性会被忽略
mapreduce应用会向资源管理器请求这个job需要的容器,一个maptask容器请求每一个maptask。一个容器对每一个maptask的请求会尝试利用map分片的本地性,应用会请求一下数据:
这只是一小部分资源任务。资源任务器在资源任务器既定目标和指定目标冲突的时候,可以忽略本地性。当一个容器被分配一个任务,map就马上启动了。
map 相的一个简要图:
现在我们可以聚焦单个的map task:这是单个map的执行时间线:
在初始化阶段,我们:
MapContext.class
, Mapper.Context.class)
SplitLineReader.class 分片行阅读器
执行阶段通过 Mapper
class.的run()方法:
用户可以重写这个方法,但是默认的时候通常会调用setup而启动这个程序。这个函数默认并不做什么有用的 事情,但是可以被用户覆盖重写以便于设置任务(例如初始化类的变量),当设置完成之后,分片的每一个键值对会激发map()方法。因此map()接收到一个键,一个值,以及一个上下文context。使用这个上下文对象,一个map就会存储其输出到缓存中。
请注意,map分片是一个快一个块截取的(例如64kb),每一个快分割成为若干键值对的数据( SplitLineReader.class干的好事
),这是在Mapper.Context.nextKeyValue内部完成的。当map分片被全部处理之后,run()会调用clean()方法。默认的,没有什么会被执行,除非用户重写覆盖他。
MapTask.MapOutputBuffer
)。缓冲区的大小是固定的,通过mapreduce.task.io.sort.mb
(default: 100MB)指定。mapreduce.map. sort.spill.percent
: 默认80% ),溢写将会被执行(这是一个并行过程,使用的是单独的线程,缓冲池还可以继续被写入)。如果溢写线程太慢,而缓冲区又忙了的话,map()就会暂停执行而等待。SpillRecord
和一个FSOutputStream
文件输出流(本地文件系统)来自: http://blog.csdn.net//mrcharles/article/details/50465626
MapReduce 图解流程超详细解答(1)-【map阶段】
标签:
原文地址:http://www.cnblogs.com/cxzdy/p/5432586.html