Hadoop源碼解析之Mapper數量計算公式

前言

  • 據說,自0.20.0版本開始,Hadoop同時提供了新舊兩套MapReduce API,並在後續版本中也同時支持這兩種API的使用。新版本MR API在舊的基礎進行了擴展,也制定了新的split計算方式。新版本MR API在包org.apache.hadoop.mapreduce及其子包中,而舊版本MR API則在包org.apache.hadoop.mapred及其子包中。
  • 本文主要從源碼角度,簡單談談新舊MR API中常用的FileInputFormat類(TextInputFormat的父類)中分片Split的計算方式,可以以此來確定每次MR的Mapper個數,默認情況下Mapper的個數即等於分片Split個數。

新舊MapReduce API的作業配置方式對比

舊API 作業配置實例:

JobConf job = new JobConf(new Configuration(), MyJob.class);
job.setJobName("myjob");
job.setMapperClass(MyJob.MyMapper.class);
job.setReducerClass(MyJob.MyReducer.class);
JobClient.runJob(job);

新API 作業配置實例:

Configuration conf = new Configuration();
Job job = new Job(conf, "myjob ");
job.setJarByClass(MyJob.class);
job.setMapperClass(MyJob.MyMapper.class);
job.setReducerClass(MyJob.MyReducer.class);
System.exit(job.waitForCompletion(true) ? 0 : 1);

分片Split計算過程

在提交MR Job時,JobsetUseNewAPI方法中根據設置的Mapper類來確定設置參數"mapred.mapper.new-api"的值,如果是使用的是舊版API,則此參數爲false,否則爲true;
然後JobSubmitter會根據參數"mapred.mapper.new-api"的值來判斷,是使用舊版還是新版API中的getSplits方法來確定分片Split。

分片Split計算過程


分片Split計算公式

由上一節圖可知,最終SplitSize的計算,在舊版本API中由org.apache.hadoop.mapred.InputFormat#getSplits方法決定,在新版本API中由org.apache.hadoop.mapreduce.InputFormat#getSplits方法決定。


舊版本FileInputFormat中分片大小splitsSize計算公式

通過查看org.apache.hadoop.mapred.FileInputFormat中的getSplits方法,可以得出對應的SplitSize計算公式:

Math.max(minSize,Math.min(goalSize,blockSize))

PS:

goalSize等於所有輸入文件的總大小除以參數"mapreduce.job.maps"的值(此參數默認值爲1,可以在 mapred-site.xml 文件中配置);

blockSize指的是當前文件在HDFS中存儲時的BLOCK大小(可以通過在 hdfs-site.xml 文件中設置"dfs.block.size"或者"dfs.blocksize"參數來調整之後新生成的HDFS文件BLOCK大小);

minSize爲參數"mapreduce.input.fileinputformat.split.minsize"的值(此參數默認值爲1,可以在 mapred-site.xml 文件中配置)。


新版本FileInputFormat中分片大小splitsSize計算公式

通過查看org.apache.hadoop.mapreduce.lib.input.FileInputFormat中的getSplits方法,可以得出對應的SplitSize計算公式:

Math.max(minSize,Math.min(maxSize,blockSize))

PS:

minSize等於參數"mapreduce.input.fileinputformat.split.minsize"的值(此參數默認值爲1,可以在 mapred-site.xml 文件中配置);

maxSize爲參數"mapreduce.input.fileinputformat.split.maxsize"的值(此參數默認值爲Long.MAX_VALUE,即0x7fffffffffffffffL,可以在 mapred-site.xml 文件中配置);

blockSize指的是當前文件在DFS中存儲時的BLOCK大小(可以通過在 hdfs-site.xml 文件中設置"dfs.block.size"或者"dfs.blocksize"參數來調整之後新生成文件的BLOCK大小)。


分片規則

當一個文件的剩餘未分片大小除以splitSize大於1.1(即超過splitSize的10%)時,則認爲文件大小“溢出”,需要切割分成多個分片,每切割一次,剩餘未分片大小減少splitSize;否則則將整個剩餘未分片的內容作爲單個分片。


FileInputFormat分片數量計算

對於輸入路徑中的每個文件都應用split分片規則來對其進行分片,每個文件至少切成一個Split(如果文件內容爲空,大小爲0,則創建空分片Split)。


Mapper個數的確定

默認情況下,Mapper的個數即等於最終的分片個數

舊版本API:

可以通過修改"mapreduce.job.maps""mapreduce.input.fileinputformat.split.minsize""dfs.blocksize" 參數來調整分片大小splitSize來調整最終分片個數,進而調整Mapper數量。

根據舊版API中splitSize計算公式,當goalSize小於blockSize,大於minSize時,Mapper數量大致等於參數"mapreduce.job.maps"的值。

新版本API:

可以通過修改"mapreduce.input.fileinputformat.split.minsize""mapreduce.input.fileinputformat.split.maxsize""dfs.blocksize" 參數來調整分片大小splitSize來調整最終分片個數,進而調整Mapper數量。

根據新版API中splitSize計算公式,一般情況下通過適當減小"mapreduce.input.fileinputformat.split.maxsize"的值,並使其置於minSize與blockSize之間,則可以減小分片大小splitSize,來增加最終分片個數,進而增加Mapper數量。


End~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章