? ? ? ?本文是Hadoop組件之MapReduce的學(xué)習(xí)總結(jié)性文章。因本人非技術(shù)出身,所學(xué)均來源于網(wǎng)絡(luò),難免有不嚴謹甚至錯誤之處,懇請大家指正。
? ? ? ?我們借用本系列第一篇文章內(nèi)舉的關(guān)于MapReduce的小例子來開始本次分享。
張三接到一個統(tǒng)計去年全年購買過“匯源腎寶”的用戶所處年齡段的任務(wù)。
? ? ? ?假設(shè)當(dāng)時他是這樣做的:寫了一個程序,先遍歷去年的數(shù)據(jù)文件,然后找到在去年所有購買過“匯源腎寶”的用戶,并且記錄下他們的年齡,最后把符合各年齡段的用戶數(shù)進行匯總統(tǒng)計,就可以得到各個年齡段的用戶數(shù)的個數(shù)。但是這種方法比較耗時,畢竟就一個程序在執(zhí)行這個任務(wù)。當(dāng)然他也可以編寫一個多線程程序,并發(fā)的去執(zhí)行這個任務(wù),這種方法肯定比前面提到的方法效率高,但是寫一個多線程程序要困難的多,不僅需要同步共享數(shù)據(jù),還要防止兩個線程重復(fù)統(tǒng)計,這對于張三來說肯定是一個有難度、并且工作量大的任務(wù)。
? ? ? ?但是在hadoop框架下,可以使用MapReduce來執(zhí)行這個任務(wù)就容易的多,大致過程為:數(shù)據(jù)文件被分成若干部分存在HDFS上(分布在不同的計算機中),然后每一臺計算機執(zhí)行一個MapReduce去計算他保存的這部分數(shù)據(jù),找出去年購買過“匯源腎寶”的用戶,并且把他們的年齡記錄下來。比如計算機A統(tǒng)計完他的數(shù)據(jù)后,20歲的用戶數(shù)有20個、30歲的用戶數(shù)有30個,計算機B統(tǒng)計完他的數(shù)據(jù)后,20歲的用戶數(shù)有22個、30歲的用戶數(shù)有30個、33歲的用戶數(shù)有60個......,這個階段可以簡單的理解為map階段。然后把所有的計算機統(tǒng)計的數(shù)據(jù)進行匯總就可以得到所有年齡的用戶數(shù)分別是多少個,假設(shè)最后匯總結(jié)果為,20歲 :1000個、30歲 :700個、33歲 :1200個,那么這個階段可以簡單的理解為reduce階段。在整個過程中張三只需要實現(xiàn)Map和Reduce這兩個函數(shù)(即按照什么鍵值對去統(tǒng)計、匯總),不用去管數(shù)據(jù)文件如何切分、統(tǒng)計不重復(fù)、匯總不遺漏等等。所以這種分布式運算的方式肯定比原來的更快,而且由于底層的技術(shù)實現(xiàn)封裝,又保證了分布式運算的準確性、便利性。
什么是MapReduce?
? ? ? ?MapReduce是一個分布式計算框架,作為產(chǎn)品人員我覺得也可以簡單粗暴的理解為他就是用于計算HDFS上數(shù)據(jù)文件的計算引擎。即HDFS是存儲大數(shù)據(jù)的,MapReduce是進行大數(shù)據(jù)運算的。
? ? ? ?既然是做計算的,那么就需要有數(shù)據(jù)輸入(input),經(jīng)過MapReduce運算后也會有個輸出(output),這個輸出就是我們所需要的結(jié)果。
一個完整的MapReduce計算任務(wù)主要有六個階段(我這樣劃分僅是為了更方便理解,當(dāng)然相對嚴謹?shù)氖莍nput包含了split):
1.input階段獲取輸入數(shù)據(jù)
2.split階段對數(shù)據(jù)進行分片作為map的輸入
3.map階段過程對某種輸入格式的一條記錄解析成一條或多條記錄
4.shffle階段對中間數(shù)據(jù)的控制,作為reduce的輸入
5.reduce階段對相同key的數(shù)據(jù)進行合并
6.output階段按照格式輸出到指定目錄
整個運算任務(wù)一般只需要程序員定義好這map函數(shù)和reduce函數(shù)即可(前面也有提到)
接下來就用圖文的方式來講解下一個MapReduce任務(wù)的具體過程,備注:本文僅針對MapReduce1.0做講解

? ? ? ?假設(shè)我們HDFS上存了一個如上圖所示的文件,這個文件中記錄了A公司去年里所有買了“匯源腎寶”的用戶的年齡。然后我們使用MapReduce來統(tǒng)計出各個年齡的人數(shù)。
1.input階段:讀取文件數(shù)據(jù)。略微擴展下:Input是讀取數(shù)據(jù)的總接口,默認使用FileInputFomart類,因為讀取的數(shù)據(jù)的類型不同(日志文件、二進制格式文件、數(shù)據(jù)庫表等等),所以FileInputFomart有多個實現(xiàn)類來處理不同類型的數(shù)據(jù),甚至可以自定義實現(xiàn)類。
2.split階段將要處理的數(shù)據(jù)進行邏輯上的切片劃分,每一個切片(split)都對應(yīng)一個mapTast任務(wù),也就是說,將數(shù)據(jù)切成幾片,就有幾個mapTast任務(wù)。心細的朋友也許會想到這里的切分與HDFS存儲數(shù)據(jù)文件時切分的Block有什么關(guān)系。那我也做個簡單的介紹,hadoop在默認的情況下,Split和Block的大小是一樣的(默認128M),這樣容易造成誤解認為兩者是一樣的,但是其實他們是2個概念,split是MapReduce里的概念,是切片的概念,split是邏輯切片,它只包含一些元數(shù)據(jù)信息(數(shù)據(jù)起始位置、數(shù)據(jù)長度、數(shù)據(jù)所在的節(jié)點等) ;而block是hdfs中切塊的大小,block是物理切塊。默認情況下一個split對應(yīng)一個block,但是實際情況可能是一個split對應(yīng)多個block。有興趣的朋友可以去這里做詳細了解 Hadoop Block 與 InputSplit 的區(qū)別與聯(lián)系。
3.map階段此階段,就是執(zhí)行mapTast任務(wù)的過程,可簡單粗暴的理解為運行多個程序(程序的數(shù)量與切片數(shù)相等,且這個程序包含程序員所寫的map()函數(shù),這個函數(shù)的作用是獲取給定文件中一行數(shù)據(jù),對其分詞后,依次輸出用戶年齡)去讀取切片對應(yīng)的數(shù)據(jù),然后輸出<20歲,1>、<30歲,1>這樣的鍵值對。
4.shffle階段簡單的理解為分組吧(如果了解SQL的,可以類比成group by),即將map的輸出經(jīng)過“整理”后給到reduce,分為map端操作和reduce端操作,這個階段是不需要程序員來做什么的,里面的代碼邏輯已經(jīng)被大佬們封裝完畢。由于比較復(fù)雜,我個人也就沒有過多去了解了。
5.reduce階段簡單的理解為對分組后的數(shù)據(jù)進行匯總(同樣可類比成分組后的 count)。當(dāng)然這個階段也會運行程序員寫的reduce()函數(shù),他的作用是將相同的年齡聚集在一起,然后統(tǒng)計每個年齡出現(xiàn)的總次數(shù),得出<20歲,1>、<30歲,1>、<33歲,1>這樣的鍵值對。
6.output階段按照輸出文件的格式,將每個鍵值對作為結(jié)果輸出。
MapReduce 1.0架構(gòu)

JobTracker是Map-Reduce框架中心(就像上一篇HDFS中NameNode一樣,把它看成指揮官),主要負責(zé)資源監(jiān)控和作業(yè)調(diào)度(管理哪些程序應(yīng)該跑在哪些些機器上)。JobTracker監(jiān)控所有TaskTracker與作業(yè)的健康狀況,一旦發(fā)現(xiàn)任務(wù)失敗情況,其會將相應(yīng)的任務(wù)轉(zhuǎn)移到其他機器上執(zhí)行;同時JobTracker會跟蹤任務(wù)的執(zhí)行進度、資源(主要就是IO、網(wǎng)絡(luò)、磁盤)使用量等,并將這些信息告訴給任務(wù)調(diào)度器(Task Scheduler),而調(diào)度器會在資源出現(xiàn)空閑時,選擇合適的任務(wù)使用這些資源。
TaskTracker會周期性地將本節(jié)點上資源的使用情況和任務(wù)的運行進度匯報給JobTracker,同時接收JobTracker發(fā)送過來的命令并執(zhí)行相應(yīng)操作(如啟動新任務(wù)、殺死任務(wù)等)。
最后做個總結(jié):
? ? ? ?MapReduce是一個分布式計算框架,具有易編程、高容錯性、高吞吐的特性。易編程主要是因為他提供了非常易用的編程接口,程序員只需要編寫幾個簡單的函數(shù)就可以實現(xiàn)分布式程序,而其他比較復(fù)雜的工作,比如節(jié)點間的通信、節(jié)點失效、數(shù)據(jù)切分等,全部由MapReduce運行環(huán)境完成,程序員們不用關(guān)注這些,只需把精力放在業(yè)務(wù)邏輯上即可。高容錯性主要是采取了計算遷移、數(shù)據(jù)遷移等策略提高集群的可用性與容錯性。高吞吐率一個分布式系統(tǒng)通常需要在高吞吐率與低延遲之間做權(quán)衡,而MapReduce選擇了高吞吐率,即利用分布式并行技術(shù),使用多機資源,一次讀取/寫入數(shù)據(jù)。同時也造成了其效率比較低,所以它一般用于離線計算,而實時計算一般使用Spark、Flink。
傳送門
Hadoop系列文章(一)數(shù)據(jù)產(chǎn)品經(jīng)理有必要了解的Hadoop
Hadoop系列文章(二)數(shù)據(jù)產(chǎn)品經(jīng)理有必要了解的HDFS
Hadoop系列文章(四)數(shù)據(jù)產(chǎn)品經(jīng)理有必要了解的YARN