【分佈式系統遨遊】分佈式計算

引言

隨着計算技術的發展,有些應用須要很是巨大的計算能力才能完成,若是採用集中式計算,須要耗費至關長的時間來完成。怎麼解決這個問題呢?固然是把這些問題分紅多份,在不一樣的機器上去解決,衆人拾柴火焰高嘛。而分佈式計算就是將該應用分解成許多小的部分,分配給多臺計算機進行處理。這樣能夠節約總體計算時間,大大提升計算效率。在分佈式中,針對這種狀況咱們大概有兩種計算模式:MapReduce和Stream,接下來就讓咱們來看看它們是何方神聖。注意:本文講述的兩種計算模式是以特定數據類型(分別對應靜態數據和動態數據)做爲計算維度。而在分佈式領域中還有另外兩種分佈式計算模式,即 Actor 和流水線。它們是以計算過程或處理過程的維度的,不作本文講述的重點。segmentfault

Map Reduce

相信你們都有據說過Hadoop這個框架,這個框架主要用來解決海量數據的計算問題。那麼它是如何作到海量數據的計算呢?你可能會想,既然是海量數據,有這麼大的規模,那就讓多個進程去處理,最後去彙總一下結果,這樣就能夠加大馬力,提高速度了。
沒錯,就是這種想法,在分佈式領域中咱們稱這種叫做MR(Map Reduce)模式。咱們上邊分紅多個進程處理的想法能夠歸結成一個詞--分而治之,是的,MR就是一個典型的分而治之(簡稱分治法)的表明。緩存

分治法是什麼

分治法就是將一個複雜的、難以直接解決的大問題,分割成一些規模較小的、能夠比較簡單的或直接求解的子問題,這些子問題之間相互獨立且與原問題形式相同,遞歸地求解這些子問題,而後將子問題的解合併獲得原問題的解。好比咱們統計全國人口數量。網絡

分治法的使用場景

  1. 問題規模比較大或複雜,且問題能夠分解爲幾個規模較小的、簡單的同類型問題進行求解;
  2. 子問題之間相互獨立,不包含公共子問題;
  3. 子問題的解能夠合併獲得原問題的解。

分治法解決問題的步驟

  1. 分解原問題。將原問題分解爲若干個規模較小,相互獨立,且與原問題形式相同的子問題。
  2. 求解子問題。若子問題規模較小且容易被解決則直接求解,不然遞歸地求解各個子問題。
  3. 合併解,就是將各個子問題的解合併爲原問題的解。

MR的抽象模型

瞭解了分治法以後,咱們再來看看本段的主角MR,以下圖所示,MapReduce 分爲 Map 和 Reduce 兩個核心階段,其中 Map 對應「分」, 即把複雜的任務分解爲若干個「簡單的任務」執行;Reduce 對應着「合」,即對 Map 階段的結果進行彙總。併發

mr1.png

在第一階段,也就是 Map 階段,將大數據計算任務拆分爲多個子任務,拆分後的子任務一般具備以下特徵: 相對於原始任務來講,劃分後的子任務與原任務是同質的,好比原任務是統計全國人口數,拆分爲統計省的人口數子任務時,都是統計人口數;而且,子任務的數據規模和計算規模會小不少。多個子任務之間沒有依賴,能夠獨立運行、並行計算,好比按照省統計人口數,統計河北省的人口數和統計湖南省的人口數之間沒有依賴關係,能夠獨立、並行的統計。
第二階段,也就是 Reduce 階段,第一階段拆分的子任務計算完成後,彙總全部子任務的 計算結果,以獲得最終結果。也就是,彙總各個省統計的人口數,獲得全國的總人口數。app

上邊瞭解了這麼多,那麼在 MapReduce 裏,各個組件是如何分工完成一個複雜任務的呢?框架

MR的工做原理

爲了解答這個問題,我先帶你瞭解一下 MapReduce 的組件結構。分佈式

mr2.png

如上圖所示,MapReduce 主要包括如下三種組件:函數

  • Master,也就是 MRAppMaster,該模塊像一個大總管同樣,獨掌大權,負責分配任 務,協調任務的運行,併爲 Mapper 分配 map() 函數操做、爲 Reducer 分配 reduce() 函數操做。
  • Mapper worker,負責 Map 函數功能,即負責執行子任務。
  • Reducer worker,負責 Reduce 函數功能,即負責彙總各個子任務的結果。

基於這三種組件,MapReduce 的工做流程以下所示:oop

mr3.png

程序從 User Program 開始進入 MapReduce 操做流程。其中圖中的「step1,step2, ...,step6」表示操做步驟。學習

  • step1:User Program 將任務下發到 MRAppMaster 中。而後MRAppMaster 執行任 務拆分步驟,把 User Program 下發的任務劃分紅 M 個子任務(M 是用戶自定義的數 值)。假設,MapReduce 函數將任務劃分紅了 5 個,其中 Map 做業有 3 個,Reduce 做 業有 2 個;集羣內的 MRAppMaster 以及 Worker 節點都有任務的副本。
  • step2:MRAppMaster 分別爲 Mapper 和 Reducer 分配相應的 Map 和 Reduce 做業。 Map 做業的數量就是劃分後的子任務數量,也就是 3 個;Reduce 做業是 2 個。
  • step3:被分配了 Map 做業的 Worker,開始讀取子任務的輸入數據,並從輸入數據中抽 取出 <key, value> 鍵值對,每個鍵值對都做爲參數傳遞給 map() 函數。
  • step4:map() 函數的輸出結果存儲在環形緩衝區 kvBuffer 中,這些 Map 結果會被按期 寫入本地磁盤中,被存儲在 R 個不一樣的磁盤區。這裏的 R 表示 Reduce 做業的數量,也是 由用戶定義的。在這個案例中,R=2。此外,每一個 Map 結果的存儲位置都會上報給 MRAppMaster。
  • step5:MRAppMaster 通知 Reducer 它負責的做業在哪個分區,Reducer 遠程讀取相 應的 Map 結果,即中間鍵值對。當 Reducer 把它負責的全部中間鍵值對都讀過來後,首 先根據鍵值對的 key 值對中間鍵值對進行排序,將相同 key 值的鍵值對彙集在一塊兒,從而 有利於 Reducer 對 Map 結果進行統計。
  • step6:Reducer 遍歷排序後的中間鍵值對,將具備相同 key 值的鍵值對合並,並將統計 結果做爲輸出文件存入負責的分區中。

從上述流程能夠看出,整個 MapReduce 的工做流程主要能夠歸納爲 5 個階段,即: Input(輸入)、Splitting(拆分)、Mapping(映射)、Reducing(化簡)以及 Final Result(輸出)。
全部 MapReduce 操做執行完畢後,MRAppMaster 將 R 個分區的輸出文件結果返回給 User Program,用戶能夠根據實際須要進行操做。好比,一般並不須要合併這 R 個輸出文 件,而是將其做爲輸入交給另外一個 MapReduce 程序處理。

舉個例子

咱們來描述一個具體的例子來幫助你們理解,假設咱們如今要統計蘇錫常地區第二季度手機訂單數量 Top3 的品牌。咱們來看看具體的統計步驟吧。

  1. 任務拆分(Splitting 階段)。根據地理位置,分別統計蘇州、無錫、常州第二季度手機 訂單 Top3 品牌,從而將大規模任務劃分爲 3 個子任務。
  2. 經過循環調用 map() 函數,統計每一個品牌手機的訂單數量。其中,key 爲手機品牌, value 爲手機購買數量(單位:萬臺)。以下圖 Mapping 階段所示(爲簡化描述,圖中 直接列出了統計結果)。
  3. 與前面講到的計算流程不一樣的是,Mapping 階段和 Reducing 階段中間多了一步 Shuffling 操做。Shuffling 階段主要是讀取 Mapping 階段的結果,並將不一樣的結果劃 分到不一樣的區。在大多數參考文檔中,Mapping 和 Reducing 階段的任務分別定義爲映 射以及歸約。可是,在映射以後,要對映射後的結果進行排序整合,而後才能執行歸約 操做,所以每每將這一排序整合的操做單獨放出來,稱之爲 Shuffling 階段。
  4. Reducing 階段,歸併同一個品牌的購買次數。
  5. 獲得蘇錫常地區第二季度 Top3 品牌手機的購買記錄。

mr4.png

由上述流程能夠看出,Map/Reduce 做業和 map()/reduce() 函數是有區別的:

  • Map 階段由必定數量的 Map 做業組成,這些 Map 做業是併發任務,能夠同時運行, 且操做重複。Map 階段的功能主要由 map() 函數實現。每一個 Map 做業處理一個子任務 (好比一個城市的手機消費統計),須要調用屢次 map() 函數來處理(由於城市內不一樣 的居民傾向於不一樣的手機)。
  • Reduce 階段執行的是彙總任務結果,遍歷 Map 階段的結果從而返回一個綜合結果。與 Reduce 階段相關的是 reduce() 函數,它的輸入是一個鍵(key)和與之對應的一組數 據(values),其功能是將具備相同 key 值的數據進行合併。Reduce 做業處理一個分 區的中間鍵值對,期間要對每一個不一樣的 key 值調用一次 reduce() 函數。在完成 Map 做 業後,每一個分區中會存在多個臨時文件;而執行完 Reduce 操做後,一個分區最終只有 一個輸出文件。

根據上文咱們知道MR模式的核心思想是分治法,在這種模式下任務完成後整個進程就結束了,並且它並不適合去處理實時任務。實時性任務主要是針對流數據的處理,對處理時延要求很高,一般須要有常駐服務進程,等待數據的隨時到來隨時處理,以保證低時延。處理流數據任務的計算模式,在分佈式領域中叫做 Stream。

流式計算

流式計算是什麼

近年來,因爲網絡監控、傳感監測、AR/VR 等實時性應用的興起,一類須要處理流數據的 業務發展了起來。好比各類直播平臺中,咱們須要處理直播產生的音視頻數據流等。這種如流水般持續涌現,且須要實時處理的數據,咱們稱之爲流數據。它有什麼特徵呢?一、數據如流水般持續、快速地到達;二、海量數據規模,數據量可達到 TB 級甚至 PB 級;三、對實時性要求高,隨着時間流逝,數據的價值會大幅下降; 四、數據順序沒法保證,也就是說系統沒法控制將要處理的數據元素的順序。那麼,在分佈式領域中,對於這種流數據的計算模式就是流計算,也叫作Stream。由於流數據大量、快速、時變的特色,因此它一般被用於處理數據密集型應用。

流式計算的工做原理

由於流式計算強調的是實時性,數據一旦產生就會被當即處理,因此在當一條數據處理完成後會序列化存儲到緩存中,而後馬上經過網絡傳輸到下一個節點,由下一個節點繼續處理,而不是像MapReduce 那樣,等到緩存寫滿纔開始處理、傳輸。爲了保證數據的實時性,在流計算中,不會存儲任何數據,就像水流同樣滾滾向前。那麼,它的處理流程是怎麼樣的呢?使用流計算進行數據處理通常會有三個步驟,參見下圖:

str1.png

  • step1:提交流式計算做業。怎麼理解呢?一個模式運行的前提你須要有必定的制度,否則流計算系統它不知道怎麼去處理數據不就搞笑了麼。因此,這一步去作的是給計算系統灌輸一個「制度」,其中包括處理節點的個數,數據轉發的規則等。另外,流式計算做業是常駐計算服務。
  • step2: 加載流式數據進行計算。流式計算在啓動後就一直處於待觸發態,等到一旦有數據過來就當即執行計算邏輯去處理。從上圖中咱們能夠看出,在流計算系統中,有多個流處理節點,流處理節點會對數據進行預約義的處理操做,並在處理完後按照某種規則轉發給後續節點繼續處理。此外,流計算系統中還存在管理節點,主要負責管理處理節點以及數據的流動規則。
  • step3:實時計算結果。流式計算做業在獲得小批量數據的計算結果後,能夠馬上將結 果數據寫入在線 / 批量系統,無需等待總體數據的計算結果,以進一步作到實時計算結果的實時展示。

小結一下,流計算是處理持續到達的數據,它並不會去存儲數據,適用於對數據處理有較高實時性要求的場景,好比網絡監控,傳感檢測,AR/VR和視頻流等實時應用。

以上咱們分別學習了MapReduce(批處理)和Stream(流式計算)模式,咱們也對它們有了一些瞭解,雖然這兩種計算模式對數據的處理方式不一樣,但都是以特定數據類型(分別對應靜態數據和動態數據)做爲計算維度。

下期預告

【分佈式系統遨遊】分佈式數據存儲

關注咱們

歡迎對本系列文章感興趣的讀者訂閱咱們的公衆號,關注博主下次不迷路~

Nosay

相關文章
相關標籤/搜索