今天在写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);