最近在學習 hadoop , 這是一個很是優秀的分佈式框架 , 在學習的過程當中也遇到了不少的問題 , 幾度讓人崩潰 , 我如今說說我遇到的問題 , 如今記錄下來和之後方便翻閱 , 同時也但願給在剛剛學習hadoop的朋友們一點小小的幫助。
java
我在看了hadoop本身的WordCount Demo後,本身也寫了一個小Demo,可是遇到了問題 ,下面我先說一下問題所在:linux
我在本地新建 了一個文件夾(in)做爲輸入文件夾,文件夾內新建了兩個文本文件 (1.txt 2.txt)apache
個人輸入文件內容以下:ubuntu
1.txt app
hello hadoop框架
hello java分佈式
hello C++ide
2.txtoop
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); } } } }