Hadoop权威指南 _04_第I部分Hadoop基础知识_第2章关于MapReduce
第I部分Hadoop基礎(chǔ)知識
第2章關(guān)于MapReduce
?
MapReduce是一種可用于數(shù)據(jù)處理的編程模型。該模型比較簡單,但要想寫出有用的程序卻不太容易。Hadoop 可以運行各種語言版本的MapReduce程序。在本章中,我們將看到同一個程序的Java、Ruby 和Python 語言版本。最重要的是,MapReduce程序本質(zhì)上是并行運行的,因此可以將大規(guī)模的數(shù)據(jù)分析任務(wù)分發(fā)給任何一個擁有足夠多機器的數(shù)據(jù)中心。MapReduce的優(yōu)勢在于處理大規(guī)模數(shù)據(jù)集,所以這里先來看一個數(shù)據(jù)集。
在本書中舉的例子是一個氣象天氣的例子。書籍寫的很好,不過我還是比較認為,如果針對WordCount會更容易理解。
根據(jù)這兩個圖進行解釋:
整個shuffle過程:
Java代碼:
https://blog.csdn.net/qq_41946557/article/details/102307454
【注】接下來的話可根據(jù)上面的圖進行分析。
在代碼中:MapReduce任務(wù)過程分為兩個處理階段:map階段和reduce階段。每階段都以鍵-值對作為輸入和輸出,其類型由程序員來選擇。程序員還需要寫兩個函數(shù): map函數(shù)和reduce函數(shù)。
首先定義一些術(shù)語。MapReduce作業(yè)(job)是客戶端需要執(zhí)行的一個工作單元:它包括輸人數(shù)據(jù)、MapReduce 程序和配置信息Hadoop 將作業(yè)分成若干個任務(wù)(task)來執(zhí)行,其中包括兩類任務(wù): map任務(wù)和reduce任務(wù)。這些任務(wù)運行在集群的節(jié)點上,并通過YARN進行調(diào)度。如果一個任務(wù)失敗,它將在另一個不同的節(jié)點上自動重新調(diào)度運行。
Hadoop將MapReduce的輸人數(shù)據(jù)劃分成等長的小數(shù)據(jù)塊,稱為輸人分片(input spli)或簡稱“分片”。Hadoop為每個分片構(gòu)建一個map任務(wù),并由該任務(wù)來運行用戶自定義的map函數(shù)從而處理分片中的每條記錄。
擁有許多分片,意味著處理每個分片所需要的時間少于處理整個輸入數(shù)據(jù)所花的時間。因此,如果我們并行處理每個分片,且每個分片數(shù)據(jù)比較小,那么整個處理過程將獲得更好的負載平衡,因為一臺較快的計算機能夠處理的數(shù)據(jù)分片比-一臺較慢的計算機更多,且成一定的比例。即使使用相同的機器,失敗的進程或其他并發(fā)運行的作業(yè)能夠?qū)崿F(xiàn)滿意的負載平衡,并且隨著分片被切分得更細,負載平衡的質(zhì)量會更高。
另一方面,如果分片切分得太小,那么管理分片的總時間和構(gòu)建map任務(wù)的總時間將決定作業(yè)的整個執(zhí)行時間。對于大多數(shù)作業(yè)來說,一個合理的分片大小趨向于HDFS的一個塊的大小,默認是128 MB,不過可以針對集群調(diào)整這個默認值(對所有新建的文件),或在每個文件創(chuàng)建時指定。
?
Hadoop在存儲有輸人數(shù)據(jù)(HDFS中的數(shù)據(jù))的節(jié)點上運行map任務(wù),可以獲得最佳性能,因為它無需使用寶貴的集群帶寬資源。這就是所謂的“數(shù)據(jù)本地化優(yōu)化”(data locality optimization)。 但是,有時對于-一個map任務(wù)的輸人分片來說,存儲該分片的HDFS數(shù)據(jù)塊復(fù)本的所有節(jié)點可能正在運行其他map任務(wù),此時作業(yè)調(diào)度需要從某一數(shù)據(jù)塊所在的機架中的一個節(jié)點上尋找一個空閑的map槽(slot)來運行該map任務(wù)分片。僅僅在非常偶然的情況下(該情況基本上不會發(fā)生),會使用其他機架中的節(jié)點運行該map 任務(wù),這將導(dǎo)致機架與機架之間的網(wǎng)絡(luò)傳輸。圖2-2 顯示了這三種可能性。
?
現(xiàn)在我們應(yīng)該清楚為什么最佳分片的大小應(yīng)該與塊大小相同:因為它是確保可以存儲在單個節(jié)點上的最大輸入塊的大小。如果分片跨越兩個數(shù)據(jù)塊,那么對于任何一個HDFS節(jié)點,基本上都不可能同時存儲這兩個數(shù)據(jù)塊,因此分片中的部分數(shù)據(jù)需要通過網(wǎng)絡(luò)傳輸?shù)絤ap任務(wù)運行的節(jié)點。與使用本地數(shù)據(jù)運行整個map任務(wù)相比,這種方法顯然效率更低。map任務(wù)將其輸出寫入本地硬盤,而非HDFS。這是為什么?因為map的輸出是中間結(jié)果:該中間結(jié)果由reduce 任務(wù)處理后才產(chǎn)生最終輸出結(jié)果,而且一且作業(yè)完成,map的輸出結(jié)果就可以刪除。因此,如果把它存儲在HDFS中并實現(xiàn)備份,難免有些小題大做。如果運行map任務(wù)的節(jié)點在將map中間結(jié)果傳送給reduce任務(wù)之前失敗,Hadoop 將在另一個節(jié)點上重新運行這個map任務(wù)以再次構(gòu)建map中間結(jié)果。
?
reduce任務(wù)并不具備數(shù)據(jù)本地化的優(yōu)勢,單個reduce 任務(wù)的輸入通常來自于所有mapper的輸出。在本例中,我們僅有一個reduce 任務(wù),其輸入是所有map任務(wù)的輸出。因此,排過序的map輸出需通過網(wǎng)絡(luò)傳輸發(fā)送到運行reduce任務(wù)的節(jié)點。數(shù)據(jù)在reduce端合并,然后由用戶定義的reduce函數(shù)處理。reduce 的輸出通常存儲在HDFS中以實現(xiàn)可靠存儲。
?
一個reduce 任務(wù)的完整數(shù)據(jù)流如圖2-3所示。虛線框表示節(jié)點,虛線箭頭表示節(jié)點內(nèi)部的數(shù)據(jù)傳輸,而實線箭頭表示不同節(jié)點之間的數(shù)據(jù)傳輸。
?
reduce任務(wù)的數(shù)量并非由輸人數(shù)據(jù)的大小決定,相反是獨立指定的。
?
如果有好多個reduce任務(wù),每個map任務(wù)就會針對輸出進行分區(qū)(partition),即為每個reduce 任務(wù)建一個分區(qū)。每個分區(qū)有許多鍵(及其對應(yīng)的值),但每個鍵對應(yīng)的鍵-值對記錄都在同一分區(qū)中。分區(qū)可由用戶定義的分區(qū)函數(shù)控制,但通常用默認的pritioner通過哈希函數(shù)來分區(qū),很高效。
?
多個reduce任務(wù)的數(shù)據(jù)流,即最開始的分析圖示。
?
最后,當(dāng)數(shù)據(jù)處理可以完全并行(即無需混洗時),可能會出現(xiàn)無reduce任務(wù)的情況(示例參見8.2.2節(jié))。在這種情況下,唯一的非本地節(jié)點數(shù)據(jù)傳輸是map任務(wù)將結(jié)果寫人HDFS(參見下圖)。
?
?集群上的可用帶寬限制了MapReduce作業(yè)的數(shù)量,因此盡量避免map和reduce任務(wù)之間的數(shù)據(jù)傳輸是有利的。
?
最后還介紹了:combiner函數(shù)、Hadoop Streaming以及使用Ruby和Python【不是很熟悉,就不多說了。】
?
總結(jié)
以上是生活随笔為你收集整理的Hadoop权威指南 _04_第I部分Hadoop基础知识_第2章关于MapReduce的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解 MySQL ——锁、事务与并发
- 下一篇: 浅析HDFS的副本存放策略