MapReducer之Mapper中的Split切片原理(即影響MapTask數目的緣由)

今天看到有朋友問到了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
來改變splits
input

源碼中的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

相關文章
相關標籤/搜索