大資料07-Hadoop框架下MapReduce中的map個數如何控制
一個job的map階段並行度由客戶端在提交job時決定
客戶端對map階段並行度的規劃基本邏輯為:
一、將待處理的檔案進行邏輯切片(根據處理資料檔案的大小,劃分多個split),然後每一個split分配一個maptask並行處理例項
二、具體切片規劃是由FileInputFormat實現類的getSplits()方法完成
切分規則如下:
1.簡單地按照檔案的內容長度進行切片
2.切片大小預設是datanode的切塊大小128M
3.切片時不是考慮一個整體資料集,而是針對每一個檔案單獨切片
比如待處理資料有兩個檔案:
file1.txt 200M
file2.txt 50M
經過FileInputFormat的切片機制運算後,形成的切片資訊如下:
file1.txt.split1– 0~128M —–maptask
file1.txt.split2– 128M~200M —–maptask
file2.txt.split1– 0~50M —–maptask
三、如何改變切片大小(引數設定)
原始碼是通過這個方法來規劃切片大小的
protected long computeSplitSize(long blockSize, long minSize, long maxSize) { return Math.max(minSize, Math.min(maxSize, blockSize)); } minsize:預設值:1;配置引數: mapreduce.input.fileinputformat.split.minsize maxsize:預設值:Long.MAXValue; 配置引數:mapreduce.input.fileinputformat.split.maxsize blocksize:hdfs切片大小
調整切片大小結論:
maxsize(切片最大值):
引數如果調得比blocksize小,則會讓切片變小,而且就等於配置的這個引數的值
minsize (切片最小值):
引數調的比blockSize大,則可以讓切片變得比blocksize還大
控制map個數的核心原始碼
long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job)); //getFormatMinSplitSize 預設返回1,getMinSplitSize 為使用者設定的最小分片數, 如果使用者設定的大於1,則為使用者設定的最小分片數 long maxSize = getMaxSplitSize(job); //getMaxSplitSize為使用者設定的最大分片數,預設最大為long 9223372036854775807L long splitSize = computeSplitSize(blockSize, minSize, maxSize); protected long computeSplitSize(long blockSize, long minSize, long maxSize) { return Math.max(minSize, Math.min(maxSize, blockSize)); }
由上述程式碼可以看出在
maxSize預設等於long(長整形)
blockSize預設在hadoop2.0之後為128M
minSize預設等於1
因此預設的切片大小splitSize等於128M也就是說等於塊大小
一個切片對應於一個map任務,因此在預設情況下一個塊對應於一個map任務。
要想人為控制map的個數可以從minSize和MaxSize入手。
想要增加map的個數,可以將maxSize調整小於blockSize;想要減小map的個數,可以調整minSize>blockSize。
具體調整可以在job配置中增加如下配置
FileInputFormat.setMinInputSplitSize(job, 301349250);//設定minSize
FileInputFormat.setMaxInputSplitSize(job, 10000);//設定maxSize
*******
總結,分片過程大概為,先遍歷目標檔案,過濾部分不符合要求的檔案, 然後新增到列表,然後按照檔名來切分分片 (大小為前面計算分片大小的公式, 最後有個檔案尾可能合併,其實常寫網路程式的都知道), 然後新增到分片列表,然後每個分片讀取自身對應的部分給MAP處理