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