标签:wordcount
最近在学习 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的输入类型为 <Object,Text>
* 输出类型为<Text. IntWritable>
*/
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{
//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 输出格式 <Text,IntWritable>
context.write(word, one);
}
}
/**
* reduce 过程
* 继承Reducer接口 设置输入类型为 <Text,IntWritable> (该输入类型正为 mapper 的输出类型)
* 输出类型为: <Text,IntWritable>
*/
public static class SumReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
//numResult 记录单词的频数
private IntWritable numResult=new IntWritable();
/**
* 重写reduce()方法
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values,
Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
int sum=0;
//对获取的<key,value-list> 计算value的和
for (IntWritable val : values) {
sum+=val.get();
}
//将频数存放到numResult 中
numResult.set(sum);
//收集结果
context.write(key, numResult);
}
}
}
}标签:wordcount
原文地址:http://botao900422.blog.51cto.com/4747129/1549681