我正在编写一个mapper函数,它将键生成为一些用户id,值也是文本类型。我是这样做的
public static class UserMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text userid = new Text();
private Text catid = new Text();
/* map method */
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString(), ","); /* separated by "," */
int count = 0;
userid.set(itr.nextToken());
while (itr.hasMoreTokens()) {
if (++count == 3) {
catid.set(itr.nextToken());
context.write(userid, catid);
}else {
itr.nextToken();
}
}
}
}
然后,在主程序中,我将Map器的输出类设置为:
Job job = new Job(conf, "Customer Analyzer");
job.setJarByClass(popularCategories.class);
job.setMapperClass(UserMapper.class);
job.setCombinerClass(UserReducer.class);
job.setReducerClass(UserReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
因此,尽管我已将输出值的类设置为text.class,但编译时仍会出现以下错误:
popularCategories.java:39: write(org.apache.hadoop.io.Text,org.apache.hadoop.io.IntWritable)
in org.apache.hadoop.mapreduce.TaskInputOutputContext<java.lang.Object,
org.apache.hadoop.io.Text,org.apache.hadoop.io.Text,
org.apache.hadoop.io.IntWritable>
cannot be applied to (org.apache.hadoop.io.Text,org.apache.hadoop.io.Text)
context.write(userid, catid);
^
根据此错误,它仍在考虑此格式的Map器类: write(org.apache.hadoop.io.Text,org.apache.hadoop.io.IntWritable)
所以,当我如下更改类定义时,问题就解决了。
public static class UserMapper extends Mapper<Object, Text, Text, Text> {
}
所以,我想了解类定义和设置mapper output vaue类之间的区别。
3条答案
按热度按时间eanckbw91#
从apache文档页
哪里
在从中更正定义中的Map器值后,问题已得到解决
至
看看相关的se问题:
为什么在Map器类中没有使用longwritable(键)?
我发现这篇文章对于清楚地理解这些概念也很有用。
ioekq8ef2#
在Map器类定义中,将outputvalue类设置为intwriteable。
但是,在mapper类中,您正在将catid示例化为文本。
即使已将mapoutputvalueclass设置为文本,也需要将Map器类的定义更改为与驱动程序中设置的键和值输出类同步。
1wnzp6jl3#
类定义同时具有输入和输出类型。例如,你的Map绘制者正在接受
Object,Text
和发射Text,Text
. 在驱动程序类中,已将Map器类的预期输出设置为Text
因此,hadoop框架希望mapper类定义具有这些输出类型,并且类发出这些输出类型Text
当你调用context.write(Text,Text)
.