hadoop(java)更改Map器输出值的类型

avwztpqn  于 2021-06-02  发布在  Hadoop
关注(0)|答案(3)|浏览(229)

我正在编写一个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类之间的区别。

eanckbw9

eanckbw91#

从apache文档页

Class Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

java.lang.Object
org.apache.hadoop.mapreduce.Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

哪里

KEYIN = offset of the record  ( input for Mapper )
VALUEIN = value of the line in the record ( input for Mapper )
KEYOUT = Mapper output key ( Output of Mapper, input of Reducer)
VALUEOUT = Mapper output value ( Output of Mapper, input to Reducer)

在从中更正定义中的Map器值后,问题已得到解决

public static class UserMapper extends Mapper<Object, Text, Text, IntWritable> {

public static class UserMapper extends Mapper<Object, Text, Text, Text> {

看看相关的se问题:
为什么在Map器类中没有使用longwritable(键)?
我发现这篇文章对于清楚地理解这些概念也很有用。

ioekq8ef

ioekq8ef2#

在Map器类定义中,将outputvalue类设置为intwriteable。

public static class UserMapper extends Mapper<Object, Text, Text, IntWritable>

但是,在mapper类中,您正在将catid示例化为文本。

private Text catid = new Text();

即使已将mapoutputvalueclass设置为文本,也需要将Map器类的定义更改为与驱动程序中设置的键和值输出类同步。

1wnzp6jl

1wnzp6jl3#

类定义同时具有输入和输出类型。例如,你的Map绘制者正在接受 Object,Text 和发射 Text,Text . 在驱动程序类中,已将Map器类的预期输出设置为 Text 因此,hadoop框架希望mapper类定义具有这些输出类型,并且类发出这些输出类型 Text 当你调用 context.write(Text,Text) .

相关问题