1.關(guān)于切片的時候保證數(shù)據(jù)完整性的問題
MapReduce在進(jìn)行切片的時候有幾個參數(shù),一個是最小切片大小(mapred.min.split.size),一個是最大切片大小(mapred.min.split.size)。
如何決定每個map輸入長度呢? 首先獲取輸入目錄下所有文件的長度和, 除以mapred.map.tasks(這個屬性是我們可以再程序中設(shè)置的)得到一個推薦長度goalSize, 然后通過公式: Math.max(minSize, Math.min(goalSize, blockSize))決定map輸入長度。 這里的minSize為mapred.min.split.size, 這個屬性是我們在配置文件中配置的,blockSize為相應(yīng)文件的block長度。這公式能保證一個map的輸入至少大于mapred.min.split.size, 對于推薦的map長度,只有它的長度小于blockSize且大于mapred.min.split.size才會有效果. 由于mapred.min.split.size默認(rèn)長度為1, 因此通常情況下只要小于blockSize就有效果,否則使用blockSize做為map輸入長度.最后個塊的大小只有大于切片的小的1.1倍才會進(jìn)行重新分片。
但是又有一個問題那就是如果完全按照大小進(jìn)行切分怎么保證每個塊最后一條數(shù)據(jù)的完整性呢?會不會有半條數(shù)據(jù)的出現(xiàn)?
實際上是不會的,LineRecordReader.java中有一段代碼
// If this is not the first split, we always throw away first record
// because we always (except the last split) read one extra line in
// next() method.
if (start != 0) {
? start += in.readLine(new Text(), 0, maxBytesToConsume(start));
}
this.pos = start;
實際上Hadoop每次進(jìn)行切分的時候每個塊都會多讀取一條數(shù)據(jù),如果是第一個塊那么就從0開始讀取,如果不是第一個塊那么就將第一條數(shù)據(jù)丟棄