我有两个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
为什么程序会出错?可能的解决方案是什么?
1条答案
按热度按时间ovfsdjhp1#
整个过程可以在Map器内部完成。使用mapper的setup函数初始化hashmap。直接在hashmap中搜索fieldid并获取其值并将其写入context。在iterable值的for循环内的reducer中输出相同的东西。