最近在学习 hadoop , 这是一个非常优秀的分布式框架 , 在学习的过程中也遇到了很多的问题 , 几度让人崩溃 , 我现在说说我遇到的问题 , 现在记录下来和以后方便翻阅 , 同时也希望给在刚刚学习hadoop的朋友们一点小小的帮助。

        我在看了hadoop自己的WordCount Demo后,自己也写了一个小Demo,但是遇到了问题 ,下面我先说一下问题所在:

         我在本地新建 了一个文件夹(in)作为输入文件夹,文件夹内新建了两个文本文件 (1.txt    2.txt)

我的输入文件内容如下:

1.txt 

    hello hadoop

    hello java

    hello C++

2.txt

    hello hadoop

    hello java

对于这两个文件我们期望得到的答案应该是:

    hello    5

    hadoop    2

    java    2

    C++    1

但是我得到的结果却是这样的:

    C++ 2

    hadoop 3

    hello 8

    java 3

这对于一个初学者来说不是很让人崩溃吗,一开始我以为我程序写错了,但是我检查了很多遍,还和hadoop自带的程序对比了,保证没有出现错误,但是是什么地方出错了呢,我试过很多方法,不知道是什么地方的问题。困扰了很久,在我使用 linux命令 ls 的时候想起来了,可能是这样的问题。下面看一张图片:

从上面的图片中,我们看一看到我的输入文件夹 in内不只有我们认为只有的1.txt 和2.txt 文件,还多了 1.txt `和2.txt` ,这样结果肯定就不正确了。

错误原因: 

因为我是手动的在in文件夹内新建了这两个文本文件, 原来在我新建文件的同时生成了两个该文件的副本,这样就出现了我一开始出现的问题,由于是刚开始使用 ubuntu系统 ,不熟悉里面的机制,相信可能会有很多初学hadoop的朋友会遇到这样的问题,希望会给大家一些帮助。

程序代码:

package cn.edu.ytu.botao.wordcount;import java.io.IOException;import java.util.StringTokenizer;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.Reducer;/** * 单词计数 * @author botao * */public class WordCount {		/**	 * map 过程	 * 继承Mapper接口 设置map的输入类型为 
 * 输出类型为
 */ public static class TokenizerMapper extends Mapper
{ //one 表示单词出现一次 private final static IntWritable one=new IntWritable(1); //word 用于存储切下的单词 private Text word=new Text(); /**  * 重写map()方法  */ @Override protected void map(Object key, Text value, Context context) throws IOException, InterruptedException { // TODO Auto-generated method stub //super.map(key, value, context); //对value(要计数的文件进行单词切割) 进行切分   StringTokenizer tokenizer=new StringTokenizer(value.toString()); //将切割后的单词取出  输出 while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); //map 输出格式  
context.write(word, one); } } /**  * reduce 过程  * 继承Reducer接口 设置输入类型为 
 (该输入类型正为 mapper 的输出类型)  * 输出类型为: 
 */ public static class SumReducer extends Reducer
{ //numResult 记录单词的频数 private IntWritable numResult=new IntWritable(); /**  * 重写reduce()方法  */ @Override protected void reduce(Text key, Iterable
 values, Context context) throws IOException, InterruptedException { // TODO Auto-generated method stub int  sum=0; //对获取的
 计算value的和 for (IntWritable val : values) { sum+=val.get(); } //将频数存放到numResult 中 numResult.set(sum); //收集结果 context.write(key, numResult); } } }}