2011-04-29 66 views
1

簡化我的問題,我有一組帶有由雙換行符分隔的「記錄」的文本文件。像使用Hadoop將文本文件中的段落處理爲單個記錄

'多行文字'

'空行'

'多行文字'

'空行'

等等。

我需要分別轉換每個多行單元,然後對它們執行mapreduce。

但是,我知道使用hadoop代碼樣板中的默認wordcount設置,以下函數中value變量的輸入只是一行,並且不能保證輸入與之前的輸入連續線。

public void map(LongWritable key, Text value, 
       OutputCollector<Text, IntWritable> output, 
       Reporter reporter) throws IOException ; 

而且我需要它,輸入value實際上是雙新行的一個單元分隔的多行文字。

一些搜索變成了一個RecordReader類和一個getSplits方法,但沒有簡單的代碼示例,我可以包裹我的頭。

另一種解決方案是用多個空格字符替換多行文本中的所有換行符,並用它來完成。我寧願不這樣做,因爲它有相當多的文本,並且在運行時方面很耗時。如果我這樣做,我也必須修改很多代碼,所以通過hadoop處理它對我來說最具吸引力。

回答

3

如果你的文件很小,那麼它們不會被分割。基本上每個文件都是一個分配給一個映射器實例的分割。在這種情況下,我同意托馬斯的觀點。您可以通過串聯字符串在您的映射器類中構建邏輯記錄。您可以通過查找作爲映射器值的空字符串來檢測您的記錄邊界。

但是,如果文件很大並且分裂,那麼除了實現您自己的文本輸入格式類別外,我沒有看到任何其他選項。您可以克隆現有的Hadoop LineRecordReader和LineReader java類。您必須對您的LineReader類的版本進行小改動,以便記錄分隔符將爲兩行,而不是一行。一旦完成,您的映射程序將收到多行作爲輸入值。

+0

當我需要處理超過64MB的文件或者hadoop開始分割文件時,您的回覆實際上會更有幫助。 – JasonMond 2011-06-17 03:26:54

1

它有什麼問題?只要將前面的行寫入StringBuilder並在達到新記錄時刷新它。
當您使用文本文件時,它們不會被分割。對於這些情況,它使用FileInputFormat,它僅與可用文件的數量並行。

+0

謝謝!我花了一段時間才真正實施和測試,但你是對的。 – JasonMond 2011-05-20 01:31:26

相關問題