首页 > 代码库 > Hadoop 学习一
Hadoop 学习一
最近在学习 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); } } } }
Hadoop 学习一