Hadoop 提供错误输出的Mapreduce字数示例

Hadoop 提供错误输出的Mapreduce字数示例,hadoop,mapreduce,word-count,Hadoop,Mapreduce,Word Count,我正在努力学习mapreduce。从中所示的WordCount示例开始,当我在eclipse中执行代码时,它的输出是正确的字数。I/p文件内容如下:- 你好,世界,再见 它的输出是 再见1 你好1 世界2 之后,我通过在输入文件中的每个单词后面用逗号替换空格来测试代码 现在我已经将输入恢复为与以前相同的状态,但现在输出中的字数是预期结果的两倍 再见2 你好2 世界4 我的代码如下: public static class TokenizerMapper extends Mapper<Obj

我正在努力学习mapreduce。从中所示的WordCount示例开始,当我在eclipse中执行代码时,它的输出是正确的字数。I/p文件内容如下:-

你好,世界,再见

它的输出是

再见1

你好1

世界2

之后,我通过在输入文件中的每个单词后面用逗号替换空格来测试代码

现在我已经将输入恢复为与以前相同的状态,但现在输出中的字数是预期结果的两倍

再见2

你好2

世界4

我的代码如下:

public static class TokenizerMapper extends Mapper<Object, Text, Text,IntWritable>{
    public static IntWritable one = new IntWritable(1);
    private Text word = new Text();
    public void map(Object key, Text value, Context context) throws IOException, InterruptedException{
        StringTokenizer itr = new StringTokenizer(value.toString());
        while (itr.hasMoreTokens()){
            word.set(itr.nextToken());
            context.write(word, one);
        }
    }
}

public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
    private IntWritable result = new IntWritable();
    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException{
        int sum=0;
        for(IntWritable val:values){
            sum +=val.get();
        }
        result.set(sum);
        context.write(key, result);
    }
}

public static void main(String[] str) throws Exception{
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "word count");
    
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    
   FileInputFormat.addInputPath(job, new Path(str[0]));
   FileOutputFormat.setOutputPath(job,new Path(str[1]));
   
   System.exit(job.waitForCompletion(true) ? 0 : 1);
    
    
}
公共静态类TokenizerMapper扩展映射器{
public static IntWritable one=新的IntWritable(1);
私有文本字=新文本();
公共void映射(对象键、文本值、上下文上下文)引发IOException、InterruptedException{
StringTokenizer itr=新的StringTokenizer(value.toString());
而(itr.hasMoreTokens()){
set(itr.nextToken());
上下文。写(单词,一);
}
}
}
公共静态类IntSumReducer扩展了Reducer{
私有IntWritable结果=新的IntWritable();
公共void reduce(文本键、Iterable值、上下文上下文)引发IOException、InterruptedException{
整数和=0;
for(可写入值:值){
sum+=val.get();
}
结果集(总和);
编写(键、结果);
}
}
公共静态void main(字符串[]str)引发异常{
Configuration conf=新配置();
Job Job=Job.getInstance(conf,“字数”);
job.setJarByClass(WordCount.class);
setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
addInputPath(作业,新路径(str[0]);
setOutputPath(作业,新路径(str[1]);
系统退出(作业等待完成(真)?0:1;
}
还有人能解释一下,在Reducer方法中,每个词的值是如何分组的,因为它对特定词的每个值进行求和,检查同一个词是否有两个计数


谢谢

必须为您提供输入文件夹作为输入路径,其中必须有两个具有相同内容的文件,这可能是重复计数的原因

这是事实,我将输入文件夹作为路径,但只有一个文件。是的,您是正确的。其他文件未通过UI显示。当我检查终端时,它就在那个里,名字是“file01~”。我删除了它,现在它正在工作。你能告诉我为什么在那里创建这个文件吗。另外,你能帮我回答我在文章中的另一个问题吗?我已经尝试了你的代码,它给了我正确的结果,只是尝试给出文件路径而不是文件夹路径,因为输入值在reducer中按键分组,在这个程序中,你在mapper中将word配置为键,所以reducer得到了按键记录,并为每个键调用了reduce方法,因此,在您的示例中,Hello、Bye和World的reduce方法调用三次,Hello的键和值数组类似于(Hello,[1]),Bye的键和值数组类似于(Bye,[1]),World的键和值数组类似于(World,[1,1]),删除同一输入文件夹中的tmp文件:)@vefthym是的,您是对的。创建了一个tmp文件。你能告诉我为什么创建这个tmp文件吗。