今天在寫MapReduce程序時遇到了Type mismatch的問題,真的非常蛋疼,折騰了好久,后來找到了問題所在。
即setOutputKeyClass() 會同時限定Mapper和Reducer的輸出 key 類型,同理,setOutputValueClass()會同時限定Mapper和Reducer的輸出value類型。如果Mapper和Reducer的輸出key或value類型不同,可以通過setMapOutputKeyClass 和 setMapOutputValueClass來設定Mapper的輸出key/value對。
舉個例子,我寫的Mapper類如下:
static class FetchMapper extends Mapper<LongWritable, Text, Text, LongWritable>{ }
而Reducer類如下:
tatic class FetchReducer extends Reducer<Text, LongWritable, Text, Text> { }
這時紅色部分表明了FetchMapper的輸出<k2,v2> 是 <Text,LongWritable> ,而 FetchReducer的輸出為<k3,v3>是 <Text,Text>。可見v2 和 v3 是不同的。此時如果用下面的設置啟動程序的話就會出現Type mismatched 錯誤:
job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class);
而加上紅色部分的代碼則可以解決這個問題。
job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); job.setMapOutputValueClass(LongWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class);