初学hadoop就要上项目,真是捉急啊!遇到这个配置问题,整了好久,更捉急!
问题是这样的:在配置mapreduce的job时,总是报
1. java.io.IOException: wrong value class: class org.apache.hadoop.io.NullWritable is not class org.apache.hadoop.io.IntWritable
或2. expected org.apache.hadoop.io.**, received org.apache.hadoop.io.**。
出错点在job.setOutputKeyClass(**.class);job.setOutputValueClass(**.class);
当配置成mapper的输出,会报第1个错误,配置成reducer的输出会报第2个错误。
百度了一下,说是如果只设置Output,所设置的是mapper和reducer的输出,如果两者输出一致,则ok,如果不一致,就会报错。于是添加了job.setMapOutputKeyClass(**.class);job.setMapOutputValueClass(**.class);
还是要报错(不要这样对我嘛!)
可是同事的配置却可以运行,话说这里他配的是和我是一样的呀。(人品问题?)
没有办法,把他的程序拿来仔细对比了一下,唯一的差异是他没有配置job.setCombinerClass,而我配了。原来如此(隐藏够深啊!让姐姐我找了半天)
分析原因:
如果配置了setCombinerClass(模板里配置了的),正确的数据流:mapper(k1,v1,k2,v2)->combine(k2,v2,k3,v3)->reducer(k3,v3,k4,v4)。但是通常把combineClass设置为reducer,这样,实际的数据流:mapper(k1,v1,k2,v2)->combine(k2,v2,k3,v3)->reducer(k2,v2,k3,v3)。肯定会出错呀。
因此,可以注释掉setCombinerClass,实在需要,再视情况而定。
另外,如果加了job.setMapOutputKeyClass(**.class); job.setMapOutputValueClass(**.class);那job.setOutputKeyClass(**.class);job.setOutputValueClass(**.class);设置为reducer的输出格式,如果没有设前者,那后者应该设置为mapper的输出格式。(亲测!正解!)