後端麵霸之旅-MapReduce探秘
來源:後端開發技術
前言
最近在看一些大資料的東西,發現對其中的shuffle過程很模糊,於是決定學習一下,深入之後又發現對整個mapreduce的資料完成處理過程也同樣模糊。
所以本文將從以下幾個角度來展開:
mapreduce以及hadoop框架的一些認識 mapreduce的核心思想是什麼 mapreduce資料處理過程推演 mapreduce的shuffle是如何實現的
Hadoop三劍客
Hadoop是一個由Apache開發的大資料處理框架,它包括了HDFS(Hadoop分散式檔案系統)、YARN(Yet Another Resource Negotiator,資源管理器)以及MapReduce計算框架。
HDFS是Hadoop的儲存元件,YARN則是用於資源管理和排程的元件,而MapReduce是Hadoop用於分散式計算的框架。
在Hadoop中,資料通常儲存在HDFS中,透過MapReduce框架進行分散式計算,YARN負責管理計算資源,並協調MapReduce等計算框架的執行。
MapReduce、Hadoop、HDFS和YARN之間是相互依存、協同工作的關係,它們共同構成了一個完整的大資料處理系統。
MapReduce核心思想
分而治之
MapReduce的主要思想是將大規模資料處理任務分解成多個小任務,並在分散式計算叢集上並行執行,從而實現高效的資料處理和分析。
MapReduce資料處理任務分為兩個主要階段:Map階段和Reduce階段。
在Map階段中,MapReduce將輸入資料分割成若干個小塊,然後在分散式計算叢集上同時執行多個Map任務,每個任務都對一個小塊的資料進行處理,並將處理結果輸出為一系列鍵值對,Map任務的輸出結果會被臨時儲存在本地磁碟或記憶體中,以供Reduce任務使用。
在Reduce階段中,它主要負責對Map任務的輸出結果進行整合和彙總,生成最終的輸出結果。Reduce任務會將所有Map任務輸出的鍵值對按照鍵進行排序,並將相同鍵的值合併在一起,Reduce任務的輸出結果通常會寫入到檔案系統中
計算向資料靠攏
在傳統的分散式計算中,資料通常需要從儲存介質中讀取到計算節點進行處理,這會造成大量的資料傳輸和網路延遲,導致計算效率較低。
"計算向資料靠攏"是MapReduce的一個設計思想,旨在最大化利用資料本地性(data locality)來提高作業的效能。
在MapReduce中,資料通常分佈在叢集的不同節點上,而處理資料的任務(Map任務和Reduce任務)儘量在資料所在的節點上執行,減少資料的網路傳輸和節點間的通訊開銷,提高作業的效能。
MapReduce過程推演
我們嘗試從頭來推演整個MapReduce任務的大致執行過程:
怎麼寫跨語言的MapReduce作業? JobClient做了些什麼? JobClient和Yarn是如何互動的? Hadoop2.x中AppMaster、NodeManager是如何協作的? 輸入檔案分割是怎麼實現的?
Hadoop Streaming
如果使用非 Java 程式語言來實現 MapReduce 任務,或者希望更靈活地定製 Map 和 Reduce 函式的實現方式,可以考慮使用 Hadoop Streaming。
Hadoop Streaming 是 Hadoop 提供的一個工具,可以讓使用者透過標準輸入和標準輸出來實現自定義 Map 和 Reduce 函式的功能。使用 Hadoop Streaming 可以使用任何語言來實現 Map 和 Reduce 函式,而不僅僅侷限於 Java。
當使用 Hadoop Streaming 時,客戶端會將 Map 和 Reduce 函式打包成可執行檔案,然後提交給 Hadoop 叢集來執行。這些可執行檔案可以用任何程式語言編寫,例如 Python、Perl、Ruby、C++ 等。
JobClient
在提交任務之前,客戶端需要將任務的輸入資料和輸出路徑等資訊設定好,以便Hadoop叢集能夠正確地執行任務並將結果輸出到指定的路徑。
MapReduce的客戶端JobClient通常會將任務打包成JAR包,然後將該JAR包提交給Hadoop叢集來執行任務。
JAR包中包含了MapReduce任務所需的輸入資料、輸出路徑、 Map 和 Reduce 的數量,以及每個任務需要的記憶體和 CPU 資源等引數,這樣可以保證任務在叢集中的任何節點上都能夠正常執行。
hadoop 1.x和2.x
在Hadoop 1.x版本中,JobTracker和TaskTracker是Hadoop叢集中的兩個重要元件,其中JobTracker負責整個叢集中所有MapReduce任務的協調和管理,而TaskTracker負責具體的任務執行。
在Hadoop 2.x版本中引入了YARN框架,將JobTracker的功能拆分成兩部分,一部分是ResourceManager,負責叢集資源的管理和分配,另一部分是ApplicationMaster,負責具體任務的管理和協調。
在Hadoop 2.x版本及以後的版本中,ApplicationMaster扮演的角色類似於JobTracker。
AppMaster
在 Hadoop YARN 中,ApplicationMaster是一個關鍵的元件,它負責在叢集中管理和監控一個特定的應用程式。
在 MapReduce 中,每個 MapReduce 作業都有一個對應的 ApplicationMaster 例項,該例項負責協調整個作業的執行過程,包括分配任務、監控任務的進度和狀態、處理任務失敗等。
當客戶端提交 MapReduce 作業時,YARN 資源管理器會為該作業啟動一個 ApplicationMaster 例項。
ApplicationMaster 將向資源管理器請求分配資源,並與各個 NodeManager 協商任務的執行。它還負責將 MapReduce 作業的邏輯劃分為多個 Map 和 Reduce 任務,並將任務分配給相應的 NodeManager 執行。
在任務執行期間,ApplicationMaster 將持續監控任務的進度和狀態,並在任務出現錯誤或失敗時進行相應的處理。
NodeManager
AppMaster和NodeManager不同,它們是YARN框架中的兩個不同的元件,分別扮演著不同的角色。
AppMaster是一個應用程式級別的元件,它執行在分散式叢集中的一個節點上,負責協調和管理應用程式的生命週期。它向ResourceManager請求資源,然後將這些資源分配給它的任務(如Map和Reduce任務)。在任務執行期間,AppMaster監視任務的進度並與ResourceManager通訊,以確保應用程式在分散式叢集上有效地執行。
NodeManager是一個節點級別的元件,它執行在每個節點上,負責管理該節點上的容器和資源。在應用程式啟動時,AppMaster向ResourceManager請求節點資源,並指示NodeManager在該節點上啟動容器來執行應用程式的任務。
NodeManager負責啟動容器併為它們分配資源,同時監視它們的進度,並向ResourceManager報告資源使用情況。
HDFS輸入檔案邏輯分割
客戶端程式中的Job物件會設定輸入檔案的路徑和InputFormat類,在提交作業之前,Job會呼叫InputFormat的getSplits()方法來獲取輸入檔案的切片資訊。
InputFormat 是針對輸入檔案進行邏輯分割,將一個或多個輸入檔案劃分為一組輸入切片InputSplit,以便於 MapReduce 作業的並行處理。
對於大多數常見的資料型別,Hadoop 提供了一些內建的 InputFormat 實現,如下:
TextInputFormat:按行讀取文字檔案,並將每行作為一個輸入記錄。 KeyValueTextInputFormat:按行讀取鍵值對形式的文字檔案,並將每個鍵值對作為一個輸入記錄。 SequenceFileInputFormat:讀取 Hadoop 序列檔案(SequenceFile),並將其中的每個 key-value 對作為一個輸入記錄。 CombineFileInputFormat:支援讀取多個小檔案或者多個小資料塊,並將它們合併成一個或多個輸入切片,以便於提高作業的並行度和執行效率。
輸入檔案的切片由InputFormat的getSplits()方法生成,這個方法會計算輸入檔案的切片,並返回一個切片陣列。每個切片都包含了一個起始偏移量和一個長度,這些資訊告訴了Map任務它需要處理的輸入資料的範圍,ResourceManager會根據Split物件陣列來計算作業需要的資源,並分配相應的資源來執行作業。
當Map任務啟動時,它會使用InputFormat提供的InputSplit資訊來建立一個RecordReader例項,用於讀取該Map任務需要處理的輸入資料。
RecordReader從HDFS或其他儲存系統中讀取資料,將資料劃分成適當大小的記錄,然後將它們轉換為鍵值對(key-value pairs),再將它們傳遞給Mapper進行處理。
shuffle簡介
先看一個完整的圖,接下來會進行展開:
什麼是shuffle
在 MapReduce 中,Map 和 Reduce 任務都是並行執行的,Map 任務負責對輸入資料進行處理,將其轉換為鍵值對的形式,而 Reduce 任務負責對 Map 任務的輸出結果進行聚合和計算。
在 MapReduce 中,Shuffle 過程的主要作用是將 Map 任務的輸出結果傳遞給 Reduce 任務,併為 Reduce 任務提供輸入資料,它是 MapReduce 中非常重要的一個步驟,可以提高 MapReduce 作業效率。
Shuffle 過程的作用包括以下幾點:
合併相同 Key 的 Value
:Map 任務輸出的鍵值對可能會包含相同的 Key,Shuffle 過程會將相同 Key 的 Value 合併在一起,減少 Reduce 任務需要處理的資料量。按照 Key 進行排序
:Shuffle 過程會將 Map 任務的輸出結果按照 Key 進行排序,這樣 Reduce 任務可以順序地處理鍵值對序列,避免在處理資料時需要進行額外的排序操作。劃分資料並傳輸
:Shuffle 過程會將 Map 任務的輸出結果按照 Key 劃分成多個分割槽,並將每個分割槽的資料傳輸到對應的 Reduce 任務中。這樣,Reduce 任務可以從不同的 Map 任務中獲取到資料,從而實現更好的並行化處理。
Map端的Shuffle
Map任務在執行過程中會將輸出的鍵值對寫入本地磁碟上的環形緩衝區中,按照Partitioner函式的規則將鍵值對對映到不同的區域Partition中。
當環形緩衝區滿或者Map任務執行完畢時,Map任務將環形緩衝區中的資料進行排序,並按照Partition和排序結果寫入到本地磁碟上的Spill檔案中。
當所有Map任務都執行完畢後,MapReduce會按照Partition對所有Spill檔案進行歸併排序,形成一個有序的大檔案。
環形緩衝區的作用
環形緩衝區是一種特殊的緩衝區,它將資料儲存在一個固定大小的、迴圈的緩衝區中,當緩衝區滿時,新的資料將覆蓋最老的資料,於連結串列和陣列等資料結構,環形緩衝區具有以下優勢:
高效的讀寫效能
:由於環形緩衝區具有固定的大小,可以預先分配一定的空間,因此讀寫操作非常高效。而且由於緩衝區是迴圈的,可以透過簡單的指標操作來實現資料的讀寫操作,而不需要複雜的資料移動操作。空間利用率高
:由於環形緩衝區可以迴圈利用空間,因此空間利用率非常高。相比於連結串列和陣列等資料結構,它不需要額外的空間來維護節點或索引等資訊,可以更好地利用記憶體空間。易於實現和管理
:由於環形緩衝區的結構非常簡單,因此易於實現和管理。可以透過一些簡單的技術來解決緩衝區溢位等問題,從而保證 Shuffle 過程的正確性。
分割槽&排序&溢寫
在 Map 階段中,Map 任務會將輸出資料寫入環形緩衝區,而這些資料會被分為多個分割槽,並且每個分割槽內的資料是按照鍵(Key)進行排序的。
分割槽的劃分是由 Partitioner 類完成的,預設情況下,Partitioner 類會根據鍵值對的鍵(Key)來計算分割槽編號(Partition ID),從而將資料分配到對應的分割槽中。
不同的鍵(Key)可能會被分到同一個分割槽中,而相同的鍵(Key)則一定會被分到同一個分割槽中,這是為了保證相同鍵(Key)的資料能夠被髮送到同一個 Reduce 任務中進行處理。
Map 任務向環形緩衝區中寫入資料時,先將資料插入到分割槽內,然後對該分割槽內的所有資料進行快速排序。
當環形緩衝區中的資料量達到一定閾值(MapReduce 1.x 中預設為環形緩衝區大小的 0.8 倍),或者某個分割槽記憶體放的資料大小達到一定閾值(MapReduce 1.x 中預設為 100MB),就會觸發溢寫操作,將資料按照分割槽寫到磁碟上的臨時檔案中。
Reduce端的Shuffle
map的shuffle階段會生成包含不同分割槽的大檔案 reduce任務可能會多個不同的分割槽,但是同一個分割槽的資料一定在同一個reduce中 reduce任務收集來自多個map輸出的同一個分割槽的資料,在內部再針對同一分割槽的多個檔案做歸併成一個大檔案
小結
很多時候明確問題比知道答案更重要,多想為什麼、多在腦海裡去推演過程、最終才能自洽吸收外界知識,化為自己的經驗。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027827/viewspace-2943528/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前端小白麵試之旅:前端
- 前端小白麵試之旅二前端
- 軟體測試麵霸的修煉心經
- 麵霸篇:Java 集合容器大滿貫(卷二)Java
- 後端工程師的「跨域」之旅後端工程師跨域
- 麵霸篇:高頻 Java 基礎問題(核心卷一)Java
- 視訊分享:過五關斬六將——我要做IT麵霸!
- Redis 麵霸篇:高頻問題橫掃核心知識點Redis
- 一個月面試4家,3家Offer,來看看麵霸真君如何面試的面試
- 探秘未來能源:太陽能發電園區的3D視覺化之旅3D視覺化
- “麵霸” 程式設計師的面試套路,這樣拿到offer的機率提高60%程式設計師面試
- 後端程式設計師的 Js 之旅 : 回撥地獄終結者後端程式設計師JS
- PayPal 後設資料之旅
- MapReduce——客戶端提交任務原始碼分析客戶端原始碼
- JavaScript客戶端測試之旅JavaScript客戶端
- ARM宮斗大戲背後的晶片產業 三大巨頭制霸食物鏈頂端晶片產業
- 《Hadoop權威指南》-- mapreduce原理讀後感Hadoop
- CabloyJS全棧開發之旅(1):NodeJS後端編譯打包全攻略全棧NodeJS後端編譯
- 遊戲產業巨無霸Steam的幕後推手遊戲產業
- Hadoop MapReduce Job提交後的互動日誌Hadoop
- 移動端 Web 開發踩坑之旅Web
- 探秘偽基站產業鏈產業
- Java 8 註解探秘Java
- PostgreSQL Cost Based Vacuum探秘SQL
- app後端和web後端的區別APP後端Web
- 雙非末流一本麵霸,十面阿里,七面頭條,4個月斬獲六個Offer!阿里
- 畢業前寫了20萬行程式碼,讓我從成為同學眼裡的麵霸!行程
- 前端後端前端後端
- MapReduce初探
- MapReduce理解
- 探秘Runtime - 深入剖析CategoryGo
- 淺談 Laravel 之探秘 SoftDeletesLaraveldelete
- 前端方便麵前端
- 淺談前後端路由與前後端渲染後端路由
- MapReduce實現之Reduce端重分割槽Join操作最佳化!
- 前端路由和後端路由,前端渲染和後端渲染前端路由後端
- MapReduce: 提高MapReduce效能的七點建議[譯]
- Node及後端後端