2013-10-27 166 views
11

通常情況下,我們寫形式的映射:映射器輸入鍵值對Hadoop中

public static class Map extends Mapper<**LongWritable**, Text, Text, IntWritable> 

這裏,輸入鍵值對的映射是<LongWritable, Text> - 據我知道什麼時候該映射得到輸入數據逐行掃描 - 所以映射器的密鑰表示行號 - 如果我錯了,請糾正我的錯誤。

我的問題是:如果我給了映射器的輸入鍵值對作爲<Text, Text>那麼它給錯誤

java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text 

它是強制性的,爲輸入鍵值對映射爲<LongWritable, Text> - 如果是,那麼爲什麼?如果沒有,那麼錯誤的原因是什麼?你能幫我理解錯誤的正確推理嗎?

在此先感謝。

+0

不強制使用'LongWritable'作爲重點。你在做什麼來產生這個異常?你的代碼在哪裏出現? – Vidya

+0

我沒有做任何明確的生成此異常 - 它顯示:: java.lang.ClassCastException:org.apache.hadoop.io.LongWritable不能轉換爲org.apache.hadoop.io.Text 在ExamTest $ Map.map(ExamTest.java:1) 在org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144) 在org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) at org.apache.hadoop.mapred.Child $ 4.run(Child.java:255) – Ronin

+0

請問您能解釋一下情況嗎?謝謝。 – Ronin

回答

30

映射器的輸入取決於使用什麼InputFormat。該InputFormat負責讀取輸入數據,並將其塑造成任何形式的映射expects.The默認InputFormat是TextInputFormat,延伸FileInputFormat<LongWritable, Text>

如果您不更改InputFormat,則使用具有不同鍵值類型簽名而不是<LongWritable, Text>的映射器將導致此錯誤。如果你期望輸入<Text, Text>,你將不得不選擇一個合適的InputFormat。您可以在作業設置中設置InputFormat:

job.setInputFormatClass(MyInputFormat.class); 

而且就像我說的,默認情況下,它被設置爲TextInputFormat。

現在,讓我們說你的輸入數據是一串用逗號分隔的換行分隔的記錄:

  • 「A,值1」
  • 「B,值2」

如果你想輸入的關鍵映射爲(「A」,「值1」),(「B」,「值2」),你將不得不實現自定義InputFormat和RecordReader與<Text, Text>簽名。 幸運的是,這很簡單。有an example here,也可能是一些浮動在StackOverflow周圍的例子。

簡而言之,添加一個擴展爲FileInputFormat<Text, Text>的類和一個擴展爲RecordReader<Text, Text>的類。覆蓋FileInputFormat#getRecordReader方法,並讓它返回自定義RecordReader的實例。然後你將不得不實現所需的RecordReader邏輯。最簡單的方法是在自定義RecordReader中創建一個LineRecordReader實例,並將所有基本職責委託給此實例。在getCurrentKey和getCurrentValue的方法,你會實現邏輯通過調用LineRecordReader#getCurrentValue和逗號分割而提取逗號分隔的文本內容。

最後,將您的新InputFormat設置爲Job InputFormat,如上面第二段後面所示。

+0

非常感謝。 很好。你能告訴我你是如何知道這件事的嗎?您想分享的任何重要鏈接? – Ronin

+0

主要由谷歌搜索和這樣撿信息步驟這些位一步,你對現在同樣的路徑。 :)但是閱讀本書的一部分Hadoop:權威指南非常有幫助。它給出了一個相當全面的Hadoop介紹。 –

+1

使用'job.setInputFormatClass(MyTextInputFormat.class)'在新的Hadoop包 – pedromateo

1

在湯姆懷特的書「Hadoop:The Difference Guide」中,我認爲他有一個合適的答案(pg。197):

「的TextInputFormat的 鍵,被簡單地將文件內的偏移,通常不是非常 有用它是在一個文件中的每個行是一個鍵 - 值對,由分隔符隔開共同 這樣。作爲製表符。例如,這是 TextOutputFormat,Hadoop的默認 OUTPUTFORMAT產生的輸出。爲了解釋這些文件正確, KeyValueTextInputFormat 是合適的。

您可以指定通過 key.value的分隔符。 separator.in.input.line property。I t 默認是一個製表符。「

+0

謝謝!我第一次讀這本書,並且我無法弄清楚Mapper的關鍵LongWritable輸入是從哪裏來的!您在這裏的評論幫助我指出了我需要的答案,您的回答爲我進一步闡明瞭這一點。 –

+0

我怎樣才能得到鍵和值之間的Java地圖減少程序的哈希值分隔符? –

-3

主要用於映射輸入將永遠是一個整型....映射器的輸入鍵指示線條偏移沒有。和的值指示整個線...... 記錄讀取器讀取在第一週期的單行。和O /映射器的p可以是任何ü希望(它可以是(文本,文本)或(文字,IntWritable)或......)

+0

這是一個長,而不是一個詮釋 –