[Hadoop] Hadoop学习历程 [持续更新中…]
1. Hadoop FS Shell
Hadoop之所以可以實(shí)現(xiàn)分布式計(jì)算,主要的原因之一是因?yàn)槠浔澈蟮姆植际轿募到y(tǒng)(HDFS)。所以,對(duì)于Hadoop的文件操作需要有一套全新的shell指令來(lái)完成,而這就是Hadoop FS Shell。它主要是用于對(duì)Hadoop平臺(tái)進(jìn)行文件系統(tǒng)的管理。
有關(guān)HDFS的介紹博客請(qǐng)移步:Hadoop學(xué)習(xí)筆記之Hadoop基礎(chǔ)。
有關(guān)Hadoop FS Shell的學(xué)習(xí)文檔:Hadoop FS Shell學(xué)習(xí)文檔。
2. Hadoop Streaming
我們知道Hadoop集群上的一些MapReduce代碼一般是利用Java來(lái)進(jìn)行開發(fā)的,那么對(duì)于很多像博主一樣的不會(huì)Java的同學(xué)該怎么辦呢,是不是我們必須要在使用Hadoop之前要學(xué)會(huì)Java呢?當(dāng)然,如果Java對(duì)你沒(méi)有什么幫助的話,你是完全沒(méi)有必要額外為了Hadoop來(lái)學(xué)習(xí)Java的。Hadoop Streaming就是Hadoop為了幫助用戶創(chuàng)建和運(yùn)行一些特殊的map/reduce作業(yè)而開發(fā)的一個(gè)工具,它可以被看做是一個(gè)API,可以使用戶很方便地利用一些腳本語(yǔ)言(比如,bash shell或者Python)來(lái)寫Mapper和Reducer。
下面是Hadoop Streaming的學(xué)習(xí)文檔:Hadoop Streaming學(xué)習(xí)文檔。
3. Hadoop的輸入和輸出
Hadoop的輸入和輸出分別為標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出,這是在學(xué)習(xí)hadoop時(shí)首先要記住的。對(duì)于第一次編寫hadoop job的同學(xué)來(lái)說(shuō),如果沒(méi)有認(rèn)識(shí)到這點(diǎn)的重要性的話,可能都不知道hadoop如何在本地進(jìn)行測(cè)試。Hadoop的輸入輸出是基于標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出的,那么我們?cè)诒镜販y(cè)試的時(shí)候就要利用bash命令來(lái)模擬這個(gè)過(guò)程,所以常見(jiàn)的unittest形式如下:
cat input | mapper | sort | reducer > output
其中的sort命令的左右是在模擬reducer輸入的過(guò)程。對(duì)于數(shù)據(jù)流而言,具有相同key的數(shù)據(jù)流會(huì)聚合在一起(但是value是無(wú)序的),而且會(huì)被分發(fā)給同一個(gè)reducer,所以sort命令主要是在模擬這個(gè)過(guò)程,關(guān)于這個(gè)問(wèn)題在下邊的combiner和partitioner部分會(huì)進(jìn)行詳細(xì)介紹。
4. Hadoop MapReduce & Shuffler
我們學(xué)習(xí)Hadoop實(shí)際上就是在學(xué)習(xí)一種全新的計(jì)算框架,它基于分布式的技術(shù)存儲(chǔ),利用MapReduce思想實(shí)現(xiàn)海量數(shù)據(jù)處理的目的。在沒(méi)有實(shí)際接觸Hadoop時(shí),很多參考書上都這樣說(shuō):MapReduce主要為兩個(gè)階段:Map階段和Reduce階段。這句話確實(shí)沒(méi)有錯(cuò),但是如果想完全的理解整個(gè)MapReduce思想,除了認(rèn)識(shí)上述兩個(gè)階段還要深刻理解一個(gè)很重要的中間過(guò)程——shuffler,其中shuffler包含了combiner和partitioner。
下圖為MapReduce的整體框架,其中shuffler部分的操作介于Mapper和Reducer之間,它的主要功能為處理Mapper的輸出并為Reducer提供相應(yīng)的輸入文件,主要操作為combiner和partitioner。
我們可以這樣來(lái)理解上述的三種中間操作:
combiner:分為Mapper端和Reducer端,主要作用是將鍵值對(duì)中具有相同key的放在一起;
partitioner:把鍵值對(duì)按照key分配給reducer。
combiner和partitioner兩者結(jié)合可以使得每一個(gè)Reducer的輸入是按照key進(jìn)行聚合的,而且同一個(gè)key所對(duì)應(yīng)的數(shù)據(jù)流只會(huì)被分配到同一個(gè)Reducer,這就極大地簡(jiǎn)化了Reducer的任務(wù)。
下圖為顯示了combiner和partitioner兩個(gè)中間操作的MapReduce框架圖,這個(gè)例子是做詞頻統(tǒng)計(jì):
?
我們可以看到combiner的作用就是按照key將Mapper的輸出進(jìn)行聚合,而partitioner會(huì)將所有combiner的結(jié)果按照key進(jìn)行分發(fā),分發(fā)給不同的Reducer進(jìn)行數(shù)據(jù)的處理。我們?cè)赗educer端可以看到兩點(diǎn):
第一,所有具有相同key的數(shù)據(jù)流均被分發(fā)到同一個(gè)Reducer;
第二,每個(gè)Reducer的輸入中數(shù)據(jù)流是按照key進(jìn)行聚合的,即具有相同key的數(shù)據(jù)流是連在一起的。
這樣我們?cè)赗educer端就可以很輕松的完成詞頻統(tǒng)計(jì)的任務(wù),我們可以按照數(shù)據(jù)流的順序進(jìn)行詞頻的統(tǒng)計(jì),如果當(dāng)前數(shù)據(jù)流的key與上一個(gè)數(shù)據(jù)流的key相同,那么就將該key對(duì)應(yīng)的詞頻進(jìn)行累加,如果不同說(shuō)明該key已經(jīng)被統(tǒng)計(jì)完成,則進(jìn)行下一個(gè)詞的統(tǒng)計(jì)即可。
此外,在hadoop的配置中我們可以為partitioner配置相應(yīng)的參數(shù)來(lái)控制partitioner按照不同的列來(lái)進(jìn)行數(shù)據(jù)的切分,hadoop的默認(rèn)設(shè)置是按照key進(jìn)行數(shù)據(jù)的切分。
其實(shí)除了combiner和partitioner以外,還有一些中間操作也需要進(jìn)行深刻的理解,比如hadoop的sort過(guò)程。在這里,我們可以簡(jiǎn)單了解一下Reducer端的sort,它其實(shí)是一種二次排序(secondary sort)。我們知道在hadoop中每個(gè)Reducer的輸入數(shù)據(jù)流中,數(shù)據(jù)流都是按照key聚合好的,但是其對(duì)應(yīng)value則是無(wú)序的,即同一個(gè)job運(yùn)行多次,由于Mapper完成的順序不同,Reducer收到的value的順序則是不固定的,那么如何才能使得Reducer接收的value成為有序的呢?這就是secondary sort需要解決的問(wèn)題,它的應(yīng)用場(chǎng)景常見(jiàn)的有求每個(gè)key下的最小/最大value值等。
此外,我們也可以通過(guò)參數(shù)來(lái)控制secondary sort相應(yīng)的作用域。
5. Hadoop常見(jiàn)操作
5.1 count操作
count(計(jì)數(shù)/統(tǒng)計(jì))是hadoop最為常見(jiàn)的操作之一。它的基本思想是就是上述詞頻統(tǒng)計(jì)的例子所講述的,由于每個(gè)Reducer的輸入都是按照key進(jìn)行聚合的,所以可以根據(jù)key來(lái)順序的進(jìn)行累加。
5.2 join操作
join(拼接)是hadoop中最為常見(jiàn)的操作之一,它的主要任務(wù)就是將多張數(shù)據(jù)表按照某個(gè)字段拼接成一個(gè)表。要想寫出join操作需要考慮周全,否則會(huì)得到意想不到的結(jié)果。(PS:我在剛開始run第一個(gè)join job的時(shí)候,發(fā)現(xiàn)輸出結(jié)果總是不對(duì),檢查了mapper和reducer的代碼邏輯覺(jué)得都沒(méi)有問(wèn)題,一直不知道是哪里出問(wèn)題,最后終于找到了原因,原來(lái)是MapReduce參數(shù)設(shè)置的問(wèn)題: Mapper的output key fields = 2(按第1,2列排序);Reducer partition fields = 1(按第一列切分給reducer作為輸入)。)
join的思想有很多種,但是常用的一種可以這樣來(lái)理解:
mapper階段:由于數(shù)據(jù)流來(lái)自不同的數(shù)據(jù)表,所以mapper是將每一個(gè)數(shù)據(jù)流進(jìn)行打標(biāo)簽(tag),用于區(qū)別不同表的數(shù)據(jù)流;
reducer階段:根據(jù)mapper中的tag來(lái)區(qū)分?jǐn)?shù)據(jù)流,并對(duì)于不同的數(shù)據(jù)流按照自己的業(yè)務(wù)需求設(shè)計(jì)不同的操作,最后將不同的表進(jìn)行拼接。
上述的join思想被稱為是reducer端拼接。
join操作還有一個(gè)巧妙的應(yīng)用就是加載大詞典,避免直接利用streaming加載一些特別大的詞典。比如,我們現(xiàn)在要處理海量的日志,命中詞典中userid的日志挑選出來(lái),問(wèn)題很簡(jiǎn)單,但是詞表很大,可能內(nèi)存不足以加載,這時(shí)候怎么辦?我們借助join的思想:將大詞典看作是一份特殊的日志,將兩份日志join后輸出即可滿足要求了。[20160519 update.]
5.3 其他操作
除了上述的count和join兩種常用的操作,hadoop還有很多操作,比如簡(jiǎn)單的字段處理操作。在簡(jiǎn)單的字段處理操作中,比如加/減某個(gè)字段,改寫某個(gè)字段,抽取某些字段等等,我們只需要mapper就可以了,此時(shí)不需要reducer進(jìn)行任何操作,這時(shí)候reducer直接輸出mapper的結(jié)果就可以了,在streaming中reducer端實(shí)際上為一個(gè)cat命令。
總結(jié)
以上是生活随笔為你收集整理的[Hadoop] Hadoop学习历程 [持续更新中…]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Android】3.22 示例22--
- 下一篇: iOS APP提交上架最新流程(转)