Hadoop教程:Hadoop基本流程和代碼范例
基本流程:
一個(gè)圖片太大了,只好分割成為兩部分。根據(jù)流程圖來(lái)說(shuō)一下具體的一個(gè)任務(wù)執(zhí)行的情況。
1. 分布式環(huán)境中客戶端創(chuàng)建任務(wù)并提交。
2. InputFormat做Map前的預(yù)處理,主要負(fù)責(zé)以下工作:
a) 驗(yàn)證輸入的格式是否符合JobConfig的輸入定義,這個(gè)在實(shí)現(xiàn)Map和構(gòu)建Conf的時(shí)候就會(huì)知道,不定義可以是Writable的任意子類。
b) 將input的文件split為邏輯上的輸入InputSplit,其實(shí)這就是在上面提到的在分布式文件系統(tǒng)中blocksize是有大小限制的,因此大文件會(huì)被劃分為多個(gè)block。
c) 通過(guò)RecordReader來(lái)再次處理inputsplit為一組records,輸出給Map。(inputsplit只是邏輯切分的第一步,但是如何根據(jù)文件中的信息來(lái)切分還需要RecordReader來(lái)實(shí)現(xiàn),例如最簡(jiǎn)單的默認(rèn)方式就是回車換行的切分)
3. RecordReader處理后的結(jié)果作為Map的輸入,Map執(zhí)行定義的Map邏輯,輸出處理后的key,value對(duì)到臨時(shí)中間文件。
4. Combiner可選擇配置,主要作用是在每一個(gè)Map執(zhí)行完分析以后,在本地優(yōu)先作Reduce的工作,減少在Reduce過(guò)程中的數(shù)據(jù)傳輸量。
5. Partitioner可選擇配置,主要作用是在多個(gè)Reduce的情況下,指定Map的結(jié)果由某一個(gè)Reduce處理,每一個(gè)Reduce都會(huì)有單獨(dú)的輸出文件。(后面的代碼實(shí)例中有介紹使用場(chǎng)景)
6. Reduce執(zhí)行具體的業(yè)務(wù)邏輯,并且將處理結(jié)果輸出給OutputFormat。
7. OutputFormat的職責(zé)是,驗(yàn)證輸出目錄是否已經(jīng)存在,同時(shí)驗(yàn)證輸出結(jié)果類型是否如Config中配置,最后輸出Reduce匯總后的結(jié)果。
代碼范例:
業(yè)務(wù)場(chǎng)景描述:
可設(shè)定輸入和輸出路徑(操作系統(tǒng)的路徑非HDFS路徑),根據(jù)訪問(wèn)日志分析某一個(gè)應(yīng)用訪問(wèn)某一個(gè)API的總次數(shù)和總流量,統(tǒng)計(jì)后分別輸出到兩個(gè)文件中。
僅僅為了測(cè)試,因此沒(méi)有去細(xì)分很多類,將所有的類都?xì)w并于一個(gè)類便于說(shuō)明問(wèn)題。
圖4 測(cè)試代碼類圖
LogAnalysiser就是主類,主要負(fù)責(zé)創(chuàng)建,提交任務(wù),并且輸出部分信息。內(nèi)部的幾個(gè)子類用途可以參看流程中提到的角色職責(zé)。具體的看看幾個(gè)類和方法的代碼片斷:
LogAnalysiser::MapClass
public static class MapClass extends MapReduceBase
implements Mapper<LongWritable, Text, Text, LongWritable>
{
public void map(LongWritable key, Text value, OutputCollector<Text, LongWritable> output, Reporter reporter)
throws IOException
&
來(lái)源:代碼農(nóng)場(chǎng)