偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

MapReduce 經(jīng)典設(shè)計,給了我們哪些架構(gòu)啟示?

開發(fā) 架構(gòu)
MapReduce 不是一個產(chǎn)品,而是一種解決問題的思路,它有多個工程實現(xiàn),Google在論文中也給出了它自己的工程架構(gòu)實現(xiàn)。

第一部分:MapReduce究竟解決什么問題。

很多時候,定義清楚問題比解決問題更難。

1. 什么是MapReduce?

它不是一個產(chǎn)品,而是一種解決問題的思路,它有多個工程實現(xiàn),Google在論文中也給出了它自己的工程架構(gòu)實現(xiàn)。

2. MapReduce這個編程模型解決什么問題?

能夠用分治法解決的問題,例如:

  • 網(wǎng)頁抓??;
  • 日志處理;
  • 索引倒排;
  • 查詢請求匯總;

畫外音:現(xiàn)實中有許多基于分治的應(yīng)用需求。

3. 為什么是Google,發(fā)明了這個模型?

Google網(wǎng)頁抓取,分析,倒排的多個應(yīng)用場景,當時的技術(shù)體系,解決不了Google大數(shù)據(jù)量高并發(fā)量的需求,Google被迫進行技術(shù)創(chuàng)新,思考出了這個模型。

畫外音:誰痛誰想辦法。

4. 為什么MapReduce對“能夠用分治法解決的問題”特別有效?

分治法,是將一個大規(guī)模的問題,分解成多個小規(guī)模的問題(分),多個小規(guī)模問題解決,再統(tǒng)籌小問題的解(合),就能夠解決大規(guī)模的問題。

5. Google MapReduce為什么能夠成功?

Google為了方便用戶使用系統(tǒng),提供給了用戶很少的接口,去解決復(fù)雜的問題。

  • Map函數(shù)接口:處理一個基于key/value(后簡稱kv)的成對(pair)數(shù)據(jù)集合,同時也輸出基于kv的數(shù)據(jù)集合;
  • Reduce函數(shù)接口:用來合并Map輸出的kv數(shù)據(jù)集合;

畫外音:MapReduce系統(tǒng)架構(gòu),能在大規(guī)模普通PC集群上實現(xiàn)并行處理,和GFS等典型的互聯(lián)網(wǎng)架構(gòu)類似。

用戶僅僅關(guān)注少量接口,不用關(guān)心并行、容錯、數(shù)據(jù)分布、負載均衡等細節(jié),又能夠解決很多實際的問題,還有這等好事!

6. 能不能舉一個例子,說明下MapReduce的Map函數(shù)與Reduce函數(shù)是如何解決實際問題的?

舉例:假設(shè)要統(tǒng)計大量文檔中單詞出現(xiàn)的個數(shù)。

(1) Map

  • 輸入KV:pair(文檔名稱,文檔內(nèi)容)
  • 輸出KV:pair(單詞,1)

畫外音:一個單詞出現(xiàn)一次,就輸出一個1。

(2) Reduce

  • 輸入KV:pair(單詞,1)
  • 輸入KV:pair(單詞,總計數(shù))

以下是一段偽代碼:Map(list<pair($doc_name, $doc_content)>){

Map(list<pair($doc_name, $doc_content)>){
    foreach(pair in list)
        foreach($word in $doc_content)
            echo pair($word, 1); // 輸出list<k,v>
}

畫外音:如果有多個Map進程,輸入可以是一個pair,不是一個list。

Reduce(list<pair($word, $count)>){// 大量(單詞,1)
    map<string,int> result;
    foreach(pair in list)
        result[$word] += $count;
    foreach($keyin result)
        echo pair($key, result[$key]); // 輸出list<k,v>
}

畫外音:即使有多個Reduce進程,輸入也是list<pair>,因為它的輸入是Map的輸出。

最早在單機的體系下計算,輸入數(shù)據(jù)量巨大的時候,處理很慢。如何能夠在短時間內(nèi)完成處理,很容易想到的思路是,將這些計算分布在成百上千的主機上,但此時,會遇到各種復(fù)雜的問題,例如:

  • 并行計算
  • 數(shù)據(jù)分發(fā)
  • 錯誤處理
  • 集群通訊

這些綜合到一起,就成為了一個困難的問題,這也是Google MapReduce工程架構(gòu)要解決的問題。

第二部分:MapReduce的核心優(yōu)化思路。

為了解決上述場景遇到的各種復(fù)雜問題,MapReduce的核心優(yōu)化思路是:

  • 并行;
  • 先分再合;

下圖簡述了MR計算“詞頻統(tǒng)計”的過程。

從左到右四個部分,分別是:

  • 輸入文件;
  • 分:M個并行的map計算實例;
  • 合:R個并行的reduce計算實例;
  • 輸出結(jié)果;

先看最后一步,reduce輸出最終結(jié)果。

可以看到,R個reduce實例并發(fā)進行處理,直接輸出最后的計數(shù)結(jié)果。

  • 實例1輸出:(a, 256)(able, 128)(emacs, 1)
  • 實例2輸出:(f*ck, 32768) (coding, 65535)
  • 實例3輸出:(vim,65535)(x, 16)(zero, 258)

畫外音:這就是總結(jié)果,可以看到vim比emacs受歡迎很多。

需要理解的是,由于這是業(yè)務(wù)計算的最終結(jié)果,一個單詞的計數(shù)不會出現(xiàn)在兩個實例里。即:如果(a, 256)出現(xiàn)在了實例1的輸出里,就一定不會出現(xiàn)在其他實例的輸出里。

畫外音:否則的話,還需要合并,就不是最終結(jié)果了。

再看中間步驟,map到reduce的過程。

可以看到,M個map實例的輸出,會作為R個reduce實例的輸入。

1. 潛在問題一:

每個map都有可能輸出(a, 1),而最終結(jié)果(a, 256)必須由一個reduce輸出,那如何保證每個map輸出的同一個key,落到同一個reduce上去呢?

這就是“分區(qū)函數(shù)”的作用。

(1) 什么是分區(qū)函數(shù)?

分區(qū)函數(shù),是使用MapReduce的用戶需要實現(xiàn)的,決定map輸出的每一個key應(yīng)當落到哪個reduce上的函數(shù)。

畫外音:如果用戶沒有實現(xiàn),會使用默認分區(qū)函數(shù)。

以詞頻統(tǒng)計的應(yīng)用為例,分區(qū)函數(shù)可能是:

  • 以[a-g]開頭的key落到第一個reduce實例;
  • 以[h-n]開頭的key落到第二個reduce實例;
  • 以[o-z]開頭的key落到第三個reduce實例;

畫外音:有點像數(shù)據(jù)庫水平切分的“范圍法”。

(2) 分區(qū)函數(shù)實現(xiàn)要點是什么?

為了保證每一個reduce實例都能夠差不多時間結(jié)束工作任務(wù),分區(qū)函數(shù)的實現(xiàn)要點是:盡量負載均衡。

畫外音:即數(shù)據(jù)均勻分攤。

上述詞頻統(tǒng)計的分區(qū)函數(shù),就不是負載均衡的,有些reduce實例處理的單詞多,有些reduce處理的單詞少,這樣就可能出現(xiàn),所有reduce實例都處理結(jié)束,最后等待一個長尾reduce的情況。

對于詞頻統(tǒng)計,負載更為均衡的分區(qū)函數(shù)為:

hash(key) % 3

畫外音:有點像數(shù)據(jù)庫水平切分的“哈希法”。

2. 潛在問題二:

每個map都有可能輸出多個(a, 1),這樣無形中增大了網(wǎng)絡(luò)帶寬資源,以及reduce的計算資源,有沒有辦法進行優(yōu)化呢?

這就是“合并函數(shù)”的作用。

(1) 什么是合并函數(shù)?

有時,map產(chǎn)生的中間key的重復(fù)數(shù)據(jù)比重很大,可以提供給用戶一個自定義函數(shù),在一個map實例完成工作后,本地就做一次合并,這樣網(wǎng)絡(luò)傳輸與reduce計算資源都能節(jié)省很多。

合并函數(shù)在每個map任務(wù)結(jié)束前都會執(zhí)行一次,一般來說,合并函數(shù)與reduce函數(shù)是一樣的,區(qū)別是:

  • 合并函數(shù)執(zhí)行map實例本地數(shù)據(jù)合并;
  • reduce函數(shù)執(zhí)行最終的合并,會收集多個map實例的數(shù)據(jù);

對于詞頻統(tǒng)計應(yīng)用,合并函數(shù)可以將:

一個map實例的多個(a, 1)合并成一個(a, $count)輸出。

最后看第一個個步驟,輸入文件到map的過程。

3. 潛在問題三:如何確定文件到map的輸入呢?

隨意即可,只要負載均衡,均勻切分輸入文件大小就行,不用管分到哪個map實例。

畫外音:無論分到那個map都能正確處理。

結(jié)論,Google MapReduce實施了一系列的優(yōu)化:

  • 分區(qū)函數(shù):保證不同map輸出的相同key,落到同一個reduce里;
  • 合并函數(shù):在map結(jié)束時,對相同key的多個輸出做本地合并,節(jié)省總體資源;
  • 輸入文件到map如何切分:隨意,切分均勻就行;

第三部分:MapReduce的工程架構(gòu)實踐。

1. 上述優(yōu)化后的執(zhí)行流程,Google MapReduce通過怎樣的工程架構(gòu)實現(xiàn)的呢?

先看下總體架構(gòu)圖,有個直觀的印象。

2. 用戶使用GoogleMR系統(tǒng),必須輸入的是什么?

(1) 輸入數(shù)據(jù),必選

畫外音:否則系統(tǒng)處理啥。

(2) map函數(shù),必選

(3) reduce函數(shù),必選

畫外音:分治法,分與合的業(yè)務(wù)邏輯。

(4) 分區(qū)函數(shù),必選

畫外音:保證同一個key,在合并階段,必須落到同一個reduce上,系統(tǒng)提供默認hash(key)法。

(5) 合并函數(shù),可選

畫外音:看用戶是否需要在map結(jié)束階段進行優(yōu)化。

3. 用戶提供各個輸入后,GoogleMR的執(zhí)行流程是什么?

畫外音:不妨假設(shè),用戶設(shè)置了M個map節(jié)點,R個reduce節(jié)點;例如:M=500,R=200。

(1) 在集群中創(chuàng)建大量可執(zhí)行實例副本(fork);

(2) 這些副本中有一個master,其他均為worker,任務(wù)的分配由master完成, M個map實例和R個reduce實例由worker完成;

(3) 將輸入數(shù)據(jù)分成M份,然后被分配到map任務(wù)的worker,從其中一份讀取輸入數(shù)據(jù),執(zhí)行用戶的map函數(shù)處理,并在本地內(nèi)存生成臨時數(shù)據(jù);

(4) 本地內(nèi)存臨時數(shù)據(jù),通過分區(qū)函數(shù),被分成R份,周期性的寫到本地磁盤,由master調(diào)度,傳給被分配到reduce任務(wù)的worker;

(5) 負責reduce任務(wù)的worker,從遠程讀取多個map輸出的數(shù)據(jù),執(zhí)行用戶的reduce函數(shù)處理,處理結(jié)果寫入輸出文件;

畫外音:可能對key要進行外部排序。

(6) 所有map和reduce的worker都結(jié)束工作后,master喚醒用戶程序,MapReduce調(diào)用返回,結(jié)果被輸出到了R個文件中。

4. GoogleMR系統(tǒng)里的master和worker是啥?

(1) master:單點master會存儲一些元數(shù)據(jù),監(jiān)控所有map與reduce的狀態(tài),記錄哪個數(shù)據(jù)要給哪個map,哪個數(shù)據(jù)要給哪個reduce,掌控全局視野,做中控;

畫外音:是不是和GFS的master非常像?

(2) worker:多個worker進行業(yè)務(wù)邏輯處理,具體一個worker是用來執(zhí)行map還是reduce,是由master調(diào)度的;

畫外音:是不是和工作線程池非常像?這里的worker是分布在多臺機器上的而已。

5. master的高可用是如何保證的?

一個簡單的方法是,將元數(shù)據(jù)固化到磁盤上,用一個shadow-master來做高可用。

畫外音:GFS不就是這么干的么?

然而現(xiàn)實情況是:沒有將元數(shù)據(jù)固化到磁盤上,元數(shù)據(jù)被存放在master的內(nèi)存里用以提高工作效率,當master掛掉后,通知用戶“任務(wù)執(zhí)行失敗”,讓其選擇重新執(zhí)行。

畫外音:

  • (單點master,掌控全局視野,能讓系統(tǒng)的復(fù)雜性降低非常多;
  • master掛掉的概率很??;
  • 不做高可用,能讓系統(tǒng)的復(fù)雜性降低非常多;

6. worker的高可用是如何保證的?

master會周期性的ping每個worker,如果超時未返回,master會把對應(yīng)的worker置為無效,把這個worker的工作任務(wù)重新執(zhí)行:

  • 如果重新執(zhí)行的是reduce任務(wù),不需要有額外的通知;
  • 如果重新執(zhí)行的是map任務(wù),需要通知執(zhí)行reduce的worker節(jié)點,輸入數(shù)據(jù)換了一個worker;

7. 隨時都可能有map或者reduce掛掉,任務(wù)完成前重新被執(zhí)行,會不會影響MR的最終結(jié)果?

在用戶輸入不變的情況下,MR的輸出一定是不變的,這就要求MR系統(tǒng)必須具備冪等性:

  • 對相同的輸入,不管哪個負責map的worker執(zhí)行的結(jié)果,一定是不變的,產(chǎn)出的R個本地輸出文件內(nèi)容也一定是不變的;
  • 對于M個map,每個map輸出的R個本地文件,只要這些輸入不變,對應(yīng)接收這些數(shù)據(jù)的reduce的worker執(zhí)行結(jié)果,一定是不變的,輸出文件內(nèi)容也一定是不變的;

8. 長尾效應(yīng)怎么解決?

一個MR執(zhí)行時間的最大短板,往往是“長尾worker”。

導(dǎo)致“長尾worker”的原因有很多:

(1) 用戶的分區(qū)函數(shù)設(shè)計得不合理,導(dǎo)致某些reduce負載不均,要處理大量的數(shù)據(jù);

畫外音:

最壞的情況,所有數(shù)據(jù)最終都落到一個reduce上,分布式并行處理,轉(zhuǎn)變?yōu)榱藛螜C串行處理;

所以,分區(qū)函數(shù)的負載均衡性,是用戶需要考慮的。

(2) 因為系統(tǒng)的原因,worker所在的機器磁盤壞了,CPU有問題,也可能導(dǎo)致任務(wù)執(zhí)行很慢;

GoogleMR有一個“備用worker”的機制,當某些worker的執(zhí)行時間超出預(yù)期時,會啟動另一個worker執(zhí)行相同的任務(wù),以嘗試解決長尾效應(yīng)。

總結(jié)

Google MapReduce架構(gòu),體現(xiàn)了很多經(jīng)典架構(gòu)實踐:

  • 單點master簡化系統(tǒng)復(fù)雜度;
  • 單點master不高可用,簡化系統(tǒng)復(fù)雜度;
  • master對worker的監(jiān)控以及重啟,保證worker高可用;
  • 冪等性,保證結(jié)果的正確性;
  • 多個worker執(zhí)行同一個任務(wù)優(yōu)化長尾問題;

參考:《GFS 經(jīng)典設(shè)計,給了我們哪些架構(gòu)啟示?

知其然,知其所以然。

思路比結(jié)論更重要。

責任編輯:趙寧寧 來源: 架構(gòu)師之路
相關(guān)推薦

2025-08-07 08:00:00

工程架構(gòu)GFS

2010-01-15 19:44:25

C++技巧

2015-08-28 09:50:47

2020-03-03 08:40:16

細腰架構(gòu)進化

2015-10-26 11:39:54

互聯(lián)網(wǎng)架構(gòu)設(shè)計分布式

2020-06-10 07:40:36

CPU內(nèi)核態(tài)多線程

2025-03-03 04:20:00

高可用架構(gòu)冗余法則

2018-03-26 10:56:04

2017-11-28 16:37:19

黑五

2017-03-14 10:54:19

AWS S3云存儲故障

2019-04-24 09:43:46

代碼開發(fā)工具

2013-01-09 16:15:31

2011-12-05 22:58:33

蘋果

2015-10-09 17:54:35

德國電信/運營商

2022-09-06 09:51:36

芯片特斯拉

2024-04-24 11:05:03

MapReduce編程大數(shù)據(jù)

2017-03-03 17:09:09

2016-12-07 09:38:53

SparkMapReduce

2024-07-12 08:28:09

聊天系統(tǒng)架構(gòu)

2015-06-18 09:59:49

點贊
收藏

51CTO技術(shù)棧公眾號