今天看到有朋友问到了MapTask的相关问题,我以为有必要发个博客结合源码整个解析一下.spa
1、首先,咱们看到Map运行的时候不一样文件启动了不一样数量的map任务,可是JOB中又没有设置map数量的配置,其实map运行时MRAppMaster请求RM资源运行的MapTask是由map前的文件切片所决定的(虽然split默认等于blocksize可是决不等同于blocksize)orm
2、原理:分发到各个节点的mapTask对文件处理时是按照一个个切片执行的继承
如图所示,默认的InputFormat为TextInputFormat 而 TextInputFormat 继承于FileInputFormat图片
@InterfaceAudience.Public
@InterfaceStability.Stable
public class TextInputFormat extends FileInputFormat<LongWritable, Text>资源
咱们再来看看FileInputFormat是怎么对文件进行切片的get
在FileInputformat中有issplit()方法(该方法设置是否对文件进行分割)和getsplits方法,getsplits中调用
computeSplitSize()方法经过return Math.max(minSize, Math.min(goalSize, blockSize))来获取splits这个源码看附件图片.因此咱们想要改变split大小(即改变mapTask)数目的时候须要在配置文件中添加参数
mapreduce.input.fileinputformat.split.minsize 和
mapreduce.input.fileinputformat.split.maxsize
来改变splitsinput
源码中的isSplitable():源码
protected boolean isSplitable(FileSystem fs, Path filename) {
return true;
}博客
默认为切割文件,若是自定义InputFormat的话能够继承FileInputFormat覆盖isSplitable方法返回falseit
源码中的getsplits主要代码段:
public InputSplit[] getSplits(JobConf job, int numSplits)
throws IOException {
......
long blockSize = file.getBlockSize();
long splitSize = computeSplitSize(goalSize, minSize, blockSize);
}
如图,调用了computeSplitSize()方法来获取splitsize
最后,看一下computeSplitSize源码:
protected long computeSplitSize(long goalSize, long minSize,
long blockSize) {
return Math.max(minSize, Math.min(goalSize, blockSize));
}
因此从中能够看出来Math.max(minSize, Math.min(goalSize, blockSize));
决定了splitsize的大小
配置文件中能够配置:
mapreduce.input.fileinputformat.split.minsize 和
mapreduce.input.fileinputformat.split.maxsize
来改变splits,从而改变mapTask的数目:
MapTask数目=filesize/splitsize+1