2013-04-23 79 views
1

假設客戶端應用程序使用FileSplit對象來讀取相應文件中的實際字節。Hadoop FileSplit reading

爲了這樣做,一個InputStream對象必須被從FileSplit創建的,通過這樣的代碼:

FileSplit split = ... // The FileSplit reference 
    FileSystem fs = ... // The HDFS reference 

    FSDataInputStream fsin = fs.open(split.getPath()); 

    long start = split.getStart()-1; // Byte before the first 

    if (start >= 0) 
    { 
     fsin.seek(start); 
    } 

流的調整由-1存在於像HadoopMapReduceLineRecordReader類的一些場景。然而,FSDataInputStreamseek()方法的文檔明確指出,在尋找位置之後,下一次讀取將來自該位置,這意味着(?)上面的代碼將是1字節關閉(?)。

所以,問題是,所有InputSplit閱讀案例都需要「-1」調整嗎?

順便說一句,如果有人想正確讀取FileSplit,尋求其啓動是不夠的,因爲每個拆分也有一個結束可能不是實際的HDFS文件的結尾相同。所以,相應的InputStream應「界定」,即具有最大的長度,如下所示:

InputStream is = new BoundedInputStream(fsin, split.getLength()); 

在這種情況下,「本地」 fsin蒸汽上面已經創建之後,org.apache.commons.io.input.BoundedInputStream類用於,實施「界限」。

UPDATE

顯然,調整是必要只用例一線LineRecordReader類,超過分割的界限,以確保它讀取完整的最後一行的一個。

關於此問題的更多詳細信息,請參閱earlier questionMAPREDUCE-772的評論。

回答

2

尋求位置0意味着下一次調用InputStream.read()將讀取字節0.尋求位置-1將最有可能拋出異常。

您在何處具體指您在討論示例和源代碼中的標準模式時?

拆分並不是必須的,因爲您注意到了 - 例如TextInputFormat和可以拆分的文件。該進程將分割記錄讀者:

  • 尋到開始索引,然後尋找下一個換行符
  • 查找下一個換行符(或EOF)並返回「行」作爲下一個記錄

重複此操作,直到找到的下一個換行符超過拆分的末尾或找到EOF。所以你看,我這種情況下分裂的實際範圍可能會從由輸入給定向右移位分裂

更新

從LineRecordReader引用該代碼塊:

if (codec != null) { 
    in = new LineReader(codec.createInputStream(fileIn), job); 
    end = Long.MAX_VALUE; 
} else { 
    if (start != 0) { 
    skipFirstLine = true; 
    --start; 
    fileIn.seek(start); 
    } 
    in = new LineReader(fileIn, job); 
} 
if (skipFirstLine) { // skip first line and re-establish "start". 
    start += in.readLine(new Text(), 0, 
         (int)Math.min((long)Integer.MAX_VALUE, end - start)); 
} 

--start聲明最有可能處理的是避免在換行符上開始拆分並將空行作爲第一條記錄返回。您可以看到,如果發生搜索,則會跳過第一行以確保文件拆分不會返回重疊記錄

+0

上面的代碼不會搜索到-1,而是以-1開頭,即前一個字節第一場之後每場比賽開始。當然,TextInputFormat使用的LineRecordReader正如你所說的那樣工作,因爲它總是讀取至少多出一個字節,並且一直延續到行尾。也許-1是爲了解決這個問題。 – PNS 2013-04-24 00:09:13

+0

你能指點我的源/展示此-1尋求行爲的示例 – 2013-04-24 00:25:13

+0

第59行http://javasourcecode.org/html/open-source/hadoop/hadoop-1.0.3/org/apache/hadoop/mapreduce/ lib/input/LineRecordReader.java.html並不尋求開始 - 1 ... – 2013-04-24 00:27:30