日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从零开始学习Hadoop--第2章 第一个MapReduce程序

發(fā)布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零开始学习Hadoop--第2章 第一个MapReduce程序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.Hadoop從頭說

1.1 Google是一家做搜索的公司

做搜索是技術難度很高的活。首先要存儲很多的數(shù)據(jù),要把全球的大部分網(wǎng)頁都抓下來,可想而知存儲量有多大。然后,要能快速檢索網(wǎng)頁,用戶輸入幾個關鍵詞找資料,越快越好,最好在一秒之內出結果。如果全球每秒有上億個用戶在檢索,只有一兩秒的檢索時間,要在全球的網(wǎng)頁里找到最合適的檢索結果,難度很大。

Google用三個最重要的核心技術解決上述問題,它們分別是GFS,MapReduceBigTableGoogle發(fā)表了它們的設計論文,但沒有將它們開源,核心競爭力不可能開源的。論文在這里,有興趣的同學可以去看看:GFShttp://labs.google.com/papers/gfs-sosp2003.pdfMapReducehttp://labs.google.com/papers/mapreduce-osdi04.pdf

Bigtablehttp://labs.google.com/papers/bigtable-osdi06.pdf

Google的論文發(fā)表之后,DougCutting等人根據(jù)論文的思想,在開源項目Nutch的基礎上實現(xiàn)了Hadoop。后來,DougCutting去了Yahoo,繼續(xù)做Hadoop。后來,Hadoop的開發(fā)和應用開始爆發(fā)了。

在對應關系上看,HadoopMapReduce對應MapReduceHadoopDistributed File System(HDFS)對應GFSHBase對應BigTable。一般我們所說的Hadoop其實是指Hadoop體系,它包括HadoopMapReduceHDFSHBase,還有其他更多的技術。


1.2MapReduceHDFS是如何工作的

先用一種有助于理解的方式描述MapReduceHDFS是如何工作的。假如有1000G的多個文本文件,內容是英文網(wǎng)頁,需要統(tǒng)計詞頻,也就是哪些單詞出現(xiàn)過,各出現(xiàn)過多少次,有1000臺計算機可供使用,要求速度越快越好。最直接的想法是,把1000G的文件分成1000份,每臺機器處理1G數(shù)據(jù)。處理完之后,其他999臺機器將處理結果發(fā)送到一臺固定的機器上,由這臺機器進行合并然后輸出結果。

Hadoop將這個過程進行自動化的處理。首先看如何存儲這1000G的文本文件。HDFS在這1000臺機器上創(chuàng)建分布式文件系統(tǒng),將1000G的文件切分成若干個固定大小的文件塊,每個塊一般是64M大小,分散存儲在這1000臺機器上。這么多機器,在運行的時候難免會出現(xiàn)有幾臺突然死機或者掛掉的情況,這導致上面存儲的文件塊丟失,會導致計算出錯。為避免這種情況,HDFS對每個文件塊都做復制,復制成35個相同的塊,放到不同的機器上,這樣死機的文件塊在其他機器上仍然可以找得到,不影響計算。

MapReduce其實是兩部分,先是Map過程,然后是Reduce過程。從詞頻計算來說,假設某個文件塊里的一行文字是”Thisis a small cat. That is a smalldog.”,那么,Map過程會對這一行進行處理,將每個單詞從句子解析出來,依次生成形如<“this”,1>, <”is”, 1>, <”a”, 1>, <”small”, 1>,<”cat”, 1>, <”that”, 1>, <”is”, 1>,<”a”, 1>, <”small”, 1>, <”dog”,1>的鍵值對,<”this”,1>表示“this”這個單詞出現(xiàn)了1次,在每個鍵值對里,單詞出現(xiàn)的次數(shù)都是1次,允許有相同的鍵值對多次出現(xiàn),比如<”is”,1>這個鍵值對出現(xiàn)了2次。Reduce過程就是合并同類項,將上述產(chǎn)生的相同的鍵值對合并起來,將這些單詞出現(xiàn)的次數(shù)累加起來,計算結果就是<“this”,1>, <”is”, 2>, <”a”, 2>, <”small”, 2>,<”cat”, 1>, <”that”, 1>, <”dog”,1>。這種方式很簡潔,并且可以進行多種形式的優(yōu)化。比如說,在一個機器上,對本地存儲的1G的文件塊先Map,然后再Reduce,那么就得到了這1G的詞頻統(tǒng)計結果,然后再將這個結果傳送到遠程機器,跟其他999臺機器的統(tǒng)計結果再次進行Reduce,就得到1000G文件的全部詞頻統(tǒng)計結果。如果文件沒有那么大,只有三四個G,就不需要在本地進行Reduce了,每次Map之后直接將結果傳送到遠程機器做Reduce

具體地,如果用Hadoop來做詞頻統(tǒng)計,流程是這樣的:

1)先用HDFS的命令行工具,將1000G的文件復制到HDFS上;

2)JavaMapReduce代碼,寫完后調試編譯,然后打包成Jar包;

3)執(zhí)行Hadoop命令,用這個Jar包在Hadoop集群上處理1000G的文件,然后將結果文件存放到指定的目錄。

4)HDFS的命令行工具查看處理結果文件。

1.3 API參考

開發(fā)過程需要的API全部在JavaAPIHadoop API,在下面兩個地方找:

Hadoop1.2.1API文檔:http://hadoop.apache.org/docs/r1.2.1/api/index.html

JavaJDK1.7API文檔:http://docs.oracle.com/javase/7/docs/api/

2. 詞頻統(tǒng)計

在這里,我們開始實現(xiàn)WordCountMapReduce。這里的WordCount程序是從Hadoop的例子代碼改編來的。

3.標準形式的MapReduce程序

所謂標準形式的MapReduce,就說需要寫MapReduce的時候,腦海里立刻跳出的就是這個形式,一個MapJava文件,一個ReduceJava文件,一個負責調用的主程序Java文件。這個標準形式已經(jīng)是最簡了,沒有多余的東東可以刪除,沒有肥肉,是干貨。寫MapReduce和主程序的時候,分別引用哪些包哪些類,每個包每個類是什么作用,這些要很清晰。如果記不住的話,將這些代碼寫幾遍,編譯調試運行,然后不看代碼,自己從頭寫出來,編譯調試運行,重復多次應該可以記住了。

3.1 目錄和文件結構

首先創(chuàng)建一個目錄wordcount_01存放源代碼、編譯和打包結果,比如將這個目錄放在/home/brian/wordcount_01

wordcount_01目錄下,有兩個子目錄,分別是src目錄和classes目錄。src目錄存放Java的源代碼,classes目錄存放編譯結果。在src目錄下,創(chuàng)建三個文件,分別是IntSumReducer.javaTokenizerMapper.javaWordCount.java。從MapReduce的角度看,TokenizerMapper.java文件是做Map的代碼,IntSumReducer.java是做Reduce的代碼,WordCount.java是主程序,負責執(zhí)行整個流程。這三個Java文件內容在下面給出。

3.2 TokenizerMapper.java文件的源代碼

packagecom.brianchen.hadoop;


importjava.io.IOException;

importjava.util.StringTokenizer;


importorg.apache.hadoop.io.IntWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Mapper;


public classTokenizerMapper

extendsMapper<Object, Text, Text, IntWritable>{

IntWritable one= new IntWritable(1);

Text word = newText();

?

public voidmap(Object key, Text value, Context context)

throwsIOException, InterruptedException {

StringTokenizeritr = new StringTokenizer(value.toString());

while(itr.hasMoreTokens()){

word.set(itr.nextToken());

context.write(word,one);

}

}

}

?

下面逐行解釋代碼,所有的類更詳細的資料其實都可以在1.3節(jié)的兩個API地址里找到:

1)“packagecom.brianchen.hadoop”

Java提供包機制管理代碼,關鍵詞就是package,可以隨意指定一個包的名字,諸如筆者的就是”com.brianchen.hadoop”,只要不跟其他的包重復就可以。為了保證包的唯一性,Sun公司推薦用公司的域名的逆序作為包名,于是大家就在代碼里看到諸如”org.apache.hadoop”之類的包名。

2)”importjava.io.IOException”

凡是以java開頭的包,在JDK1.7API里找類的資料。這一句從javaio包里導入IOExceptionIOException,輸入輸出異常類。所謂異常,就是Exception,就是程序出錯了,異常機制是Java的錯誤捕獲機制。那么,IOException就是處理輸入輸出錯誤時候的異常,IInputOOutput

3)“import java.util.StringTokenizer”

javautil包引入StringTokenizer類。StringTokenizer將符合一定格式的字符串拆分開。比如說,”Thisis a cat”是一個字符串,這四個單詞是用空格符隔開的,那么StringTokenizer可以將它們拆成四個單詞”This”,“is”,”a”,“cat”。如果是用其他符號隔開,也能處理,比如”14;229;37”這個字符串,這三個數(shù)字是分號隔開的,StringTokenizer將它們拆成”14”,“229”,“37”。只要指定了分隔符,StringTokenizer就可以將字符串拆開。“拆開”的術語叫“解析”。

4)”importorg.apache.hadoop.io.IntWritable”

凡是以org.apache.hadoop開頭的包,在Hadoop1.2.1API找類的詳細信息。從hadoopio包里引入IntWritable類。IntWritable類表示的是一個整數(shù),是一個以類表示的整數(shù),是一個以類表示的可序列化的整數(shù)。在Java里,要表示一個整數(shù),假如是15,可以用int類型,int類型是Java的基本類型,占4個字節(jié),也可以用Integer類,Integer類封裝了一個int類型,讓整數(shù)成為類。Integer類是可以序列化的。但Hadoop覺得Java的序列化不適合自己,于是實現(xiàn)了IntWritable類。至于什么是序列化,這個問題比較長,這個問題會在后面章節(jié)詳細講。

5)“import org.apache.hadoop.io.Text”

hadoopio包里引入Text類。Text類是存儲字符串的可比較可序列化類。

6)“import org.apache.hadoop.mapreduce.Mapper”

Mapper類很重要,它將輸入鍵值對映射到輸出鍵值對,也就是MapReduce里的Map過程。

7)”publicclass TokenizerMapper extends Mapper<Object, Text, Text,IntWritable>”

定義一個自己的Map過程,類名是TokenizerMapper,它繼承了HadoopMapper類。“<Object,Text, Text,IntWritable>”,這里,第一個參數(shù)類型是Object,表示輸入鍵key的參數(shù)類型,第二個參數(shù)參數(shù)類型是Text,表示輸入值的類型,第三個參數(shù)類型也是Text,表示輸出鍵類型,第四個參數(shù)類型是IntWritable,表示輸出值類型。

在這個例子里,第一個參數(shù)ObjectHadoop根據(jù)默認值生成的,一般是文件塊里的一行文字的行偏移數(shù),這些偏移數(shù)不重要,在處理時候一般用不上,第二個參數(shù)類型是要處理的字符串,形如”Thisis a cat.”。經(jīng)過Map處理之后,輸出的就是諸如<”This”,1>的鍵值對,這個”This”就是第三個參數(shù)類型,是Text類型,而1就是第四個參數(shù)類型,是IntWritable

8)“IntWritableone = new IntWritable(1)”

定義輸出值,始終是1

9)“Text word = new Text()”

定義輸出鍵。

10)“public void map(Object key, Text value, Context context) throwsIOException, InterruptedException ”

定義map函數(shù),函數(shù)有三個參數(shù),key是輸入鍵,它是什么無所謂,實際上用不到它的,value是輸入值。在map函數(shù)中,出錯的時候會拋出異常,所以有“throwsIOException, InterruptedException”。至于Context類,這個類的定義是在TokenizerMapper的祖先類Mapper的內部,不需要引入,如果去查看Mapper類的源代碼的話,能看到Context類是繼承MapContext類的。

11)“StringTokenizer itr = new StringTokenizer(value.toString())”

定義StringTokenizer對象itrStringTokenizer的構造函數(shù)只接受JavaString類,而valueText類,所以要進行轉化,將value轉成String類,也就是“value.toString()”

12)Map過程

while(itr.hasMoreTokens()){

word.set(itr.nextToken());

context.write(word,one);

}

在默認的情況下,StringTokenizer以空格符作為分隔符對字符串進行解析,每次解析會先調用hasMoreTokens看看是不是需要做解析,如果需要做,就用nextToken()函數(shù)獲取解析結果,然后用這個結果給word賦值,然后,再將wordone作為一個鍵值對寫到context里,context會存儲鍵值留待Reduce過程處理。

3.3IntSumReducer.java文件的源代碼



packagecom.brianchen.hadoop;


importjava.io.IOException;


importorg.apache.hadoop.io.IntWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Reducer;


public classIntSumReducer extends

Reducer<Text,IntWritable,Text,IntWritable>{

IntWritableresult = new IntWritable();


public voidreduce(Text key, Iterable<IntWritable> values, Contextcontext)

throwsIOException, InterruptedException {

int sum = 0;

for(IntWritable val : values) {

sum +=val.get();

}

result.set(sum);

context.write(key,result);

}

}


跟上節(jié)相同的地方就不解釋了,只解釋上節(jié)沒有的東東。

1)”importorg.apache.hadoop.mapreduce.Reducer”

引入hadoopReducer類,這個類負責MapReduceReduce過程。

2)“public class IntSumReducer extendsReducer<Text,IntWritable,Text,IntWritable> “

定義Reduce過程,也就是IntSumReducer類,這個類繼承HadoopReducer類。這里的”<Text,IntWritable,Text,IntWritable>”,含義跟上一節(jié)一樣,依次分別是輸入鍵類型,輸入值類型,輸出鍵類型,輸出值類型。

3)“IntWritableresult = new IntWritable()”

定義輸出結果,這是一個整數(shù)。

4)“public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException ”

定義reduce函數(shù)。key是輸入鍵類型,values是一個實現(xiàn)了Iterable接口的變量,可以把它理解成values里包含若干個IntWritable整數(shù),可以通過迭代的方式遍歷所有的值,至于Context類型,跟Mapper里的Context類似的方式,是在Redurer類內部實現(xiàn)的。

舉例來說,假如處理一個字符串”Thisis a That isa“,那么,經(jīng)過Map過程之后,到達reduce函數(shù)的時候,依次傳遞給reduce函數(shù)的是:key=”This”values=<1>key= “is”values=<1,1>key = “a”,values=<1, 1>key=”That”,values=<1>。注意,在key= “is”key=”a”的時候,values里有兩個1

5)Reduce過程

intsum = 0;

for(IntWritable val : values) {

sum +=val.get();

}

result.set(sum);

context.write(key,result);

這個過程,就是用一個循環(huán),不斷從values里取值,然后累加計算和,循環(huán)結束后,將累加和賦值給result變量,然后,將鍵值和累加和作為一個鍵值對寫入context。繼續(xù)以上一步的例子來說,寫入context的鍵值對依次就是<”This”1><“is”2><“a”,2><”That”, 1>

3.4WordCount.java文件的源代碼

packagecom.brianchen.hadoop;


importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.IntWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Job;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

importorg.apache.hadoop.util.GenericOptionsParser;


public classWordCount {

public staticvoid main(String[] args) throws Exception {

Configurationconf = new Configuration();

String[]otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();

if(otherArgs.length != 2) {

System.err.println("Usage:wordcount <in> <out>");

System.exit(2);

}


Job job = newJob(conf, "wordcount");

job.setJarByClass(WordCount.class);

job.setMapperClass(TokenizerMapper.class);

job.setReducerClass(IntSumReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job,new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job,new Path(otherArgs[1]));

System.exit(job.waitForCompletion(true)? 0 : 1);

}

}

1)”importorg.apache.hadoop.conf.Configuration”

Configuration類,顧名思義,讀寫和保存各種配置資源。

2)“import org.apache.hadoop.fs.Path”

引入Path類,Path類保存文件或者目錄的路徑字符串。

3)“import org.apache.hadoop.mapreduce.Job”

引入Job類。在hadoop里,每個需要執(zhí)行的任務是一個Job,這個Job負責很多事情,包括參數(shù)配置,設置MapReduce細節(jié),提交到Hadoop集群,執(zhí)行控制,查詢執(zhí)行狀態(tài),等等。

4)”importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat”

引入FileInputFormat類。這個類的很重要的作用就是將文件進行切分split,因為只有切分才可以并行處理。這個會在后面章節(jié)有詳細解釋。

5)“import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat”

引入FileOutputFormat類,處理結果寫入輸出文件。

6)“import org.apache.hadoop.util.GenericOptionsParser”

引入GenericOptionsParser類,這個類負責解析hadoop的命令行參數(shù)。

7)”publicclass WordCount ”

這是wordcount主類,它負責讀取命令行參數(shù),配置Job,調用MapperReducer,返回結果等等工作。

8)“Configurationconf = new Configuration()”

默認情況下,Configuration開始實例化的時候,會從Hadoop的配置文件里讀取參數(shù)。

9)”String[]otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs()”

讀取參數(shù)分兩步,上一步是從Hadoop的配置文件讀取參數(shù),這一步是從命令行參數(shù)讀取參數(shù),args是存放命令行參數(shù)的字符串數(shù)組。

10)“if (otherArgs.length != 2) ”

如果命令行參數(shù)不是2個,就出錯了,退出。因為程序需要知道處理的是哪個輸入文件,處理結果放到哪個目錄,必須是兩個參數(shù)。

11)”Job job = new Job(conf, "wordcount")”

每個運行的處理任務就是一個Job,”worodcount”Job的名字。

12)“ job.setJarByClass(WordCount.class)”

Jar文件是Java語言的一個功能,可以將所有的類文件打包成一個Jar文件,setJarByClass的意思是,根據(jù)WordCount類的位置設置Jar文件。

13)“job.setMapperClass(TokenizerMapper.class)”

設置Mapper

14)“job.setReducerClass(IntSumReducer.class)”

設置Reducer

15)“job.setOutputKeyClass(Text.class)”

設置輸出鍵的類型。

16)“job.setOutputValueClass(IntWritable.class)”

設置輸出值的類型。

17)“FileInputFormat.addInputPath(job, new Path(otherArgs[0]))”

設置要處理的文件,也就是輸入文件,它是otherArgs的第一個參數(shù)。

18)“FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]))”

設置輸出文件,將處理結果寫到這個文件里,它是otherArgs的第二個參數(shù)。

19)“System.exit(job.waitForCompletion(true) ? 0 : 1)”

最后一步,job開始執(zhí)行,等待執(zhí)行結束。

3.5 編譯

javac編譯項目。javacJavaprogramming language compiler,是JavaJDK的命令行編譯器。如前所說,wordcount_01目錄存放源代碼和編譯結果,要在這個目錄下進行編譯。

3.5.1“cd ~/wordcount_01”

先執(zhí)行這個命令,切換目錄到wordcount_01下。

3.5.2“javac -classpath/home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar:/home/brian/usr/hadoop/hadoop-1.2.1/lib/commons-cli-1.2.jar-d ./classes/ ./src/*.java”

執(zhí)行這條命令,編譯源代碼。-classpath,設置源代碼里使用的各種類的庫文件路徑,路徑之間用”:”隔開,-d參數(shù),設置編譯后的class文件存在路徑。

3.6 打包

3.6.1“jar -cvf wordcount.jar -C ./classes/ .”

將編譯好的class文件打包成Jar包,jar命令是JDK的打包命令行工具,跟tar非常像。在命令里,-C是值在執(zhí)行jar的時候將目錄切換到當前目錄下的classes目錄,這個目錄包含編譯好的class文件。打包結果是wordcount.jar文件,放在當前目錄下。

3.7 執(zhí)行

3.7.1首先要確實一下Hadoop已經(jīng)運行起來了。啟動方式就是第1章的第7節(jié)。然后,執(zhí)行

3.7.2“cd ~/usr/hadoop/hadoop-1.2.1”

切換目錄到Hadoop的安裝目錄下。

3.7.3“./bin/hadoop fs -put READER.txt readme.txt”

仍然用README.txt做測試,將它復制到HDFS上,更名為readme.txt

3.7.4“./bin/hadoop fs -rmr output”

處理結果要放在HDFSoutput目錄里,如果這個目錄已經(jīng)存在了,Hadoop是不會運行的,會報錯,先刪除它。

3.7.5“./bin/hadoop jar /home/brian/wordcount_01/wordcount.jarcom.brianchen.hadoop.WordCount readme.txt output”

運行程序,處理readme.txt文件,將結果寫入output目錄,其中”jar”參數(shù)是指定jar包的位置,而”com.brianchen.hadoop.WordCount”,這里”com.brianchen.hadoop”是包的名字,“WordCount”是主類,注意,如果不寫包名字會報錯的,必須有包名。

3.8 查看結果

3.8.1“./bin/hadoop fs -cat output/part-r-00000”

處理結果output目錄的part-r-00000文件里,用cat命令可以輸出到屏幕顯示。

4.最簡形式的MapReduce

最簡單形式的WordCountMapReduce代碼是Hadoop自帶的例子,略作改動放在這里。這個例子只有一個Java文件,MapperReducer都寫在WordCount類的內部。

4.1 目錄和文件結構

代碼放在~/wordcount_02目錄,它有兩個子目錄,分別是classessrcclasses目錄存放編譯結果,src目錄存放源代碼,src目錄下只有一個java文件,即”WordCount.java”,所有的代碼都在里面。

4.2WordCount.java文件的源代碼

packagecom.brianchen.hadoop;


importjava.io.IOException;

importjava.util.StringTokenizer;


importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.IntWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Job;

importorg.apache.hadoop.mapreduce.Mapper;

importorg.apache.hadoop.mapreduce.Reducer;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

importorg.apache.hadoop.util.GenericOptionsParser;


public classWordCount {

public staticclass TokenizerMapper

extendsMapper<Object, Text, Text, IntWritable>{

private finalstatic IntWritable one = new IntWritable(1);

private Textword = new Text();


public voidmap(Object key, Text value, Context context)

throwsIOException, InterruptedException {

StringTokenizeritr = new StringTokenizer(value.toString());

while(itr.hasMoreTokens()){

word.set(itr.nextToken());

context.write(word,one);

}

}

}


public staticclass IntSumReducer extends

Reducer<Text,IntWritable,Text,IntWritable>{

privateIntWritable result = new IntWritable();

public voidreduce(Text key, Iterable<IntWritable> values, Contextcontext)

throwsIOException, InterruptedException {

int sum =0;

for(IntWritable val : values) {

sum +=val.get();

}

result.set(sum);

context.write(key,result);

}

}


public staticvoid main(String[] args) throws Exception {

Configurationconf = new Configuration();

String[]otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();

if(otherArgs.length != 2) {

System.err.println("Usage:wordcount <in> <out>");

System.exit(2);

}


Job job = newJob(conf, "word count");

job.setJarByClass(WordCount.class);

job.setMapperClass(TokenizerMapper.class);

job.setCombinerClass(IntSumReducer.class);

job.setReducerClass(IntSumReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job,new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job,new Path(otherArgs[1]));

System.exit(job.waitForCompletion(true)? 0 : 1);

}

}


這里的代碼,跟前一節(jié)有點不太一樣。

1)”publicstatic class TokenizerMapper”

這表示TokenizerMapper類是WordCount類的內部靜態(tài)類,這種方式可以將TokenizerMapper隱藏在WordCount類內部,且TokenizerMapper類不引用WordCount類的任何變量和函數(shù)。

2)“private final static IntWritable one”

跟上一節(jié)的定義相比,這里多了”privatefinalstatic”,”private”表示這個變量是類的私有變量,“final”表示這變量只能在定義的時候被賦值一次,以后不可更改,”static”表示這是一個靜態(tài)變量,獨立于對象,被該類的所有實例共享,這種做法的好處是,one這個值是私有的不可更改的僅僅只有一個,代碼更可靠,更節(jié)省內存空間。

4.3 編譯

4.3.1“cd ~/wordcount_02”

4.3.2“javac -classpath/home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar:/home/brian/usr/hadoop/hadoop-1.2.1/lib/commons-cli-1.2.jar-d ./classes/ ./src/WordCount.java ”

4.4 打包

4.4.1“jar -cvf wordcount.jar -C ./classes/ . ”

4.5 運行

4.5.1“cd ~/usr/bin/hadoop/hadoop-1.2.1”

4.5.2“./bin/hadoop fs -rmr output”

4.5.3“./bin/hadoop jar /home/brian/wordcount_02/wordcount.jarcom.brianchen.hadoop.WordCount readme.txt output”

4.6 查看結果

4.6.1“./bin/hadoop fs -cat output/part-r-00000”

?

轉載于:https://www.cnblogs.com/pangblog/p/3395249.html

總結

以上是生活随笔為你收集整理的从零开始学习Hadoop--第2章 第一个MapReduce程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。