package cn.edu.nuist.wordcount;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.TextOutputFormat;
/**
*
* 描述:WordCount explains
* @author Hadoop Dev Group
*/
public class WordCount
{
private static String inPath = "/countWords/number.txt";
private static String outPath = "/countWords/output";
private static String hdfs = "hdfs://10.255.248.61:9000"; //這裏配置集羣中master主機IP和端口號
/**
* MapReduceBase類:實現了Mapper和Reducer接口的基類(其中的方法只是實現接口,而未作任何事情)
* Mapper接口:
* WritableComparable接口:實現WritableComparable的類可以相互比較。所有被用作key的類應該實現此接口。
* Reporter 則可用於報告整個應用的運行進度,本例中未使用。
*
*/
public static class Map extends MapReduceBase implements
Mapper<LongWritable, Text, Text, IntWritable>
{
/**
* LongWritable, IntWritable, Text 均是 Hadoop 中實現的用於封裝 Java 數據類型的類,這些類實現了WritableComparable接口,
* 都能夠被串行化從而便於在分佈式環境中進行數據交換,你可以將它們分別視爲long,int,String 的替代品。
*/
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
/**
* Mapper接口中的map方法:
* void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter)
* 映射一個單個的輸入k/v對到一箇中間的k/v對
* 輸出對不需要和輸入對是相同的類型,輸入對可以映射到0個或多個輸出對。
* OutputCollector接口:收集Mapper和Reducer輸出的<k,v>對。
* OutputCollector接口的collect(k, v)方法:增加一個(k,v)對到output
*/
public void map(LongWritable key, Text value,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException
{
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens())
{
word.set(tokenizer.nextToken());
output.collect(word, one);
}
}
}
public static class Reduce extends MapReduceBase implements
Reducer<Text, IntWritable, Text, IntWritable>
{
public void reduce(Text key, Iterator<IntWritable> values,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException
{
int sum = 0;
while (values.hasNext())
{
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
}
}
public static void main(String[] args) throws Exception
{
/**
* JobConf:map/reduce的job配置類,向hadoop框架描述map-reduce執行的工作
* 構造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等
*/
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount"); //設置一個用戶定義的job名稱
conf.set("fs.default.name", hdfs);
conf.setOutputKeyClass(Text.class); //爲job的輸出數據設置Key類
conf.setOutputValueClass(IntWritable.class); //爲job輸出設置value類
conf.setMapperClass(Map.class); //爲job設置Mapper類
conf.setCombinerClass(Reduce.class); //爲job設置Combiner類
conf.setReducerClass(Reduce.class); //爲job設置Reduce類
conf.setInputFormat(TextInputFormat.class); //爲map-reduce任務設置InputFormat實現類
conf.setOutputFormat(TextOutputFormat.class); //爲map-reduce任務設置OutputFormat實現類
/**
* InputFormat描述map-reduce中對job的輸入定義
* setInputPaths():爲map-reduce job設置路徑數組作爲輸入列表
* setInputPath():爲map-reduce job設置路徑數組作爲輸出列表
*/
//設置輸入輸出文件路徑
FileSystem fs = FileSystem.get(conf);
Path inputPath = new Path(inPath);
if(fs.exists(inputPath)) {
FileInputFormat.setInputPaths(conf, inputPath);
}
Path outputPath = new Path(outPath);
fs.delete(outputPath, true);
FileOutputFormat.setOutputPath(conf, outputPath);
JobClient.runJob(conf); //運行一個job
}
}
運行後refreshHDFS文件系統,可以得到輸出文件的信息:MapReduce實現WordCount以及常見問題解決
Hadoop環境開發環境測試
最近在做一個大數據方面的小工程,需要使用基於hadoop環境進行計算。MapReduce是Hadoop生態系統下的成熟的計算框架,在開發之前需要搭建MapReduce開發環境並測試。
由於我本身就是大數據方面的新手,因此在開始的時候遇到不小的麻煩,但在慢慢的尋找解決辦法的過程中還是有所感悟的,因此有必要做一下記錄,希望給讀者有所幫助!
通常我們需要在搭好的hadoop環境下進行“wordcount”程序測試,好看是否能夠正常運行。一開始一般是不能直接成功運行WordCount程序的,因爲在windows系統下,system32文件下缺少必要文件“winutils.exe”,另外在hadoop版本文件bin目
step1:向HDFS上傳一個包含一以下內容的txt文件number.txt
對文件數據使用MapReduce編程:
在windows系統下進行MapReduce開發需要不小功夫的配置,好了,第一個wordCount程序已經成功編譯了,下面就可以正式開始功能程序的編寫啦!
望每天進步一點!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.