reducer任务没有按预期运行

9njqaruj  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(352)

我有两个hadoopMap任务的输入文件。
程序的输入是 input.txt 每行包含 PaperID keyword1 keyword2 FieldID ```
p20 k j f3
p21 k j f11
p22 k j f3
p23 k j f2
p23 k j f1

文件 `sammap.txt` 用于reducer类中包含的每一行 `FieldID FieldName` ```
f1 AI
f2 DB
f3 DB
f4 AI

代码如下:包dorado;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class Dorado {

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

    private Text word = new Text();
    public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        String str = value.toString().replaceAll(" +", " ").trim(), fir="", lst="";
        if (!str.equals("")) {
            fir = str.substring(0, str.indexOf(" "));
            lst = str.substring(str.lastIndexOf(" ")+1);

            context.write(new Text(fir), new Text(lst));
        }

    }
  }

  public static class IntSumReducer
       extends Reducer<Text,Text,Text,Text> {
  //  private IntWritable result = new IntWritable();
    private HashMap<Text, Text> fieldToClass = new HashMap<>();
    public void reduce(Text key, Iterable <Text> value,Context context) throws IOException, InterruptedException {
        FileReader fr = new FileReader("sammap.txt");
        BufferedReader br = new BufferedReader(fr);
        String str=null;
        while ((str = br.readLine()) != null) {
            String st[] = str.split(" +");
            fieldToClass.put(new Text(st[0].trim()), new Text(st[1].trim()));

            //System.out.println("--"+st[0].trim()+"--"+ st[1].trim()+"--");
        }
        fr.close();

        for (Text field : value) {
            System.out.println(key + "-->" + field);

            if (fieldToClass.containsKey(field))
                context.write(key, fieldToClass.get(field));
        }

    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "dorado");
    job.setJarByClass(Dorado.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

哈希图 fieldToClass 键为fieldid,值为fieldname。
控制台上reducer类中以下代码段的输出:

for (Text field : value) {
    System.out.println(key + "-->" + field);
    if (fieldToClass.containsKey(field))
        context.write(key, fieldToClass.get(field));
}

这是:

p20-->DB
p22-->DB
p23-->AI
p23-->DB

但是,我们希望输出的形式是:

p20-->f3
p22-->f3
p23-->f1
p23-->f2

程序的最终输出文件中也没有输出。文件为空。
我们在文件中期望的正确输出是:

p20 DB
p22 DB
p23 DB
p23 AI

为什么程序会出错?可能的解决方案是什么?

ovfsdjhp

ovfsdjhp1#

整个过程可以在Map器内部完成。使用mapper的setup函数初始化hashmap。直接在hashmap中搜索fieldid并获取其值并将其写入context。在iterable值的for循环内的reducer中输出相同的东西。

相关问题