大媽也能看懂的大數(shù)據(jù)分布式計算圖解
前言
本文是一篇科普性質(zhì)的文章,希望能通過一個通俗易懂的例子給大家講清楚大數(shù)據(jù)分布式計算技術(shù)。大數(shù)據(jù)技術(shù)雖然包含存儲、計算和分析等一系列龐雜的技術(shù),但分布式計算一直是其核心,想要了解大數(shù)據(jù)技術(shù),不妨從MapReduce分布式計算模型開始。該理論模型并不是什么新理念,早在2004年就被Google發(fā)布,經(jīng)過十多年的發(fā)展,儼然已經(jīng)成為了當(dāng)前大數(shù)據(jù)生態(tài)的基石,可謂大數(shù)據(jù)技術(shù)之道,在于MapReduce。
傳統(tǒng)計算技術(shù)
在進(jìn)入到分布式計算技術(shù)這個概念之前,我們要先回顧一下傳統(tǒng)計算技術(shù),為了使計算機(jī)領(lǐng)域的相關(guān)概念能夠生動形象深入淺出,我將計算機(jī)類比為人:

在這張圖中我們建立了計算機(jī)基本元件的類比關(guān)系,并不嚴(yán)謹(jǐn)?shù)阋哉f明問題。有了這個類比關(guān)系,我們可以把計算機(jī)領(lǐng)域的問題轉(zhuǎn)換為我們熟悉的人類領(lǐng)域的問題。從現(xiàn)在開始,每個人,比如你自己就是一臺計算機(jī),我們代稱為“人型計算機(jī)”,你擁有基本的計算機(jī)元件,上帝是個程序員,可以編寫程序——一系列設(shè)定好的指令,讓你完成一些計算任務(wù)。
下面我們要用一個簡單的案例,分析“人型計算機(jī)”是如何利用傳統(tǒng)計算技術(shù)解決實(shí)際問題的。在開始之前,要增加一些限定,如同正常計算機(jī)的內(nèi)存是有上限的,我們的“人型計算機(jī)”也存在記憶力的上限,這里我們假設(shè)一個“人型計算機(jī)”最多可以同時在“內(nèi)存”中記住4種信息,例如:蘋果、梨等四種水果的個數(shù):

看起來這臺“人型計算機(jī)”的性能比較差,不過好在我們需要處理的問題也不復(fù)雜:有幾十張不包含大王和小王的撲克牌,這些牌的花色和大小均不確定(并不一定能湊成一副牌),如何給一臺“人型計算機(jī)”設(shè)計一個程序,統(tǒng)計各個花色的撲克牌數(shù)量?

你的答案可能脫口而出:對于“人型計算機(jī)”而言,直接在大腦中記住每個花色的個數(shù),一張一張地取撲克牌計數(shù),處理完所有的撲克牌之后報4個花色的個數(shù)就行。答案完全正確,正常計算機(jī)最簡單的計算模式就是這樣的,內(nèi)存中記錄統(tǒng)計結(jié)果,隨著輸入設(shè)備不斷讀取數(shù)據(jù),更新內(nèi)存中的統(tǒng)計結(jié)果,最后從輸出設(shè)備展示結(jié)果:

接下來問題的難度要升級了,統(tǒng)計這些撲克牌中A~K共13種牌面每種牌面的個數(shù)。我們的“程序”該如何升級?

我們察覺到,如果仍然沿用之前的解決思路,“人型計算機(jī)”的“內(nèi)存”已經(jīng)不夠用了,因?yàn)槠浯鎯ι舷逓?種信息,無法存儲A~K這13種牌面信息。聯(lián)系一下現(xiàn)實(shí)生活中的場景,當(dāng)我們發(fā)現(xiàn)自己無法記住很多信息時,會用賬本來輔助記憶,對于計算機(jī)來說是一樣的,內(nèi)存不足就使用磁盤來存放信息,這時候,賬本就可以類比于一個存放于“磁盤”的Excel文檔:
那么統(tǒng)計牌面這個問題的解決思路就有了:每取一張撲克牌,在賬本中更新相應(yīng)牌型的統(tǒng)計個數(shù),數(shù)完所有的撲克牌之后直接報出結(jié)果:
單個計算機(jī)的傳統(tǒng)計算模式就是這樣,可以簡單概括為按照一定統(tǒng)一規(guī)則對輸入數(shù)據(jù)進(jìn)行加減乘除等數(shù)學(xué)運(yùn)算,然后輸出結(jié)果的過程,這中間產(chǎn)生的數(shù)據(jù)會存儲在內(nèi)存或硬盤中。在上面的案例中,撲克牌是“人型計算機(jī)”的“輸入數(shù)據(jù)“,相當(dāng)于計算機(jī)二進(jìn)制世界中可以被識別的數(shù)字和文本。統(tǒng)計的撲克牌個數(shù)是“輸出結(jié)果“,則相當(dāng)于你可以在電腦屏幕上看到的信息。
實(shí)際上,憑借內(nèi)存、硬盤和CPU等基本組件,單個計算機(jī)(不只包括個人電腦,智能手機(jī)也算)已經(jīng)可以完成我們上網(wǎng)聽歌看電影等日常基本需求中所涉及到的計算,只要計算不超出CPU的極限(譬如圍棋人機(jī)對戰(zhàn)之類的)是妥妥沒問題的,而且我們還有優(yōu)化內(nèi)存、優(yōu)化硬盤等多種手段來增強(qiáng)單個計算機(jī)的計算能力,從而滿足人民群眾日益增長的物質(zhì)與文化生活的需要。
好了,背景知識已經(jīng)足夠了,讓我們進(jìn)入正題
大數(shù)據(jù)分布式計算
首先,什么是分布式計算?簡單點(diǎn)理解就是將大量的數(shù)據(jù)分割成多個小塊,由多臺計算機(jī)分工計算,然后將結(jié)果匯總。這些執(zhí)行分布式計算的計算機(jī)叫做集群,我們?nèi)匀谎永m(xù)前文中人和計算機(jī)的類比,那么集群就是一個團(tuán)隊(duì),單兵作戰(zhàn)的時代已經(jīng)過去,團(tuán)隊(duì)合作才是王道:

為什么需要分布式計算?因?yàn)?ldquo;大數(shù)據(jù)”來了,單個計算機(jī)不夠用了,即數(shù)據(jù)量遠(yuǎn)遠(yuǎn)超出單個計算機(jī)的處理能力范圍:有時候是單位時間內(nèi)的數(shù)據(jù)量大,比如在12306網(wǎng)上買票,每秒可能有數(shù)以萬計的訪問;也有可能是數(shù)據(jù)總量大,比如百度搜索引擎,要在服務(wù)器上檢索數(shù)億的中文網(wǎng)頁信息。
實(shí)現(xiàn)分布式計算的方案有很多,在大數(shù)據(jù)技術(shù)出現(xiàn)之前就已經(jīng)有科研人員在研究,但一直沒有被廣泛應(yīng)用。直到2004年Google公布了MapReduce之后才大熱了起來。大數(shù)據(jù)技術(shù)、分布式計算和MapReduce的關(guān)系可以用下圖來描述,MapReduce是分布式計算在大數(shù)據(jù)領(lǐng)域的應(yīng)用:
MapReduce模型是經(jīng)過商業(yè)實(shí)踐的成熟的分布式計算框架,與Google的分布式文件系統(tǒng)GFS、分布式數(shù)據(jù)存儲系統(tǒng)BigTable一起,號稱Google的大數(shù)據(jù)“三寶”,為大數(shù)據(jù)技術(shù)的發(fā)展提供了堅實(shí)的理論基礎(chǔ)。但遺憾的是,谷歌并沒有向外界公布自己的商業(yè)產(chǎn)品,而真正讓大數(shù)據(jù)技術(shù)大踏步前進(jìn)的是按照Google理論實(shí)現(xiàn)的開源免費(fèi)產(chǎn)品Hadoop,目前已經(jīng)形成了以Hadoop為核心的大數(shù)據(jù)技術(shù)生態(tài)圈。
讓我們回到數(shù)撲克牌這個例子中,大數(shù)據(jù)時代的撲克牌問題是什么樣子的?
- 輸入數(shù)據(jù)的規(guī)模增加:撲克牌暴增到數(shù)萬張;
- 中間運(yùn)算數(shù)據(jù)的規(guī)模增加:問題又升級了,我們需要統(tǒng)計52種牌型每種牌型出現(xiàn)的次數(shù);
- 處理時間有限制:我們希望能盡快得到統(tǒng)計結(jié)果。
怎么樣,有沒有感覺到大數(shù)據(jù)撲面而來?要知道我們“人型計算機(jī)”的“內(nèi)存“和“硬盤”是有容量限制的,52種牌型的信息已經(jīng)超出了單臺計算機(jī)的處理能力。當(dāng)然這里會有人提出質(zhì)疑,認(rèn)為擴(kuò)充內(nèi)存或者磁盤容量就可以解決這個問題,52種牌型完全不需要分布式計算。那大家考慮一下假如這堆牌中有幾百種、甚至幾千種牌型呢?
所以52種牌是為了符合現(xiàn)實(shí)中的情況,讓大家領(lǐng)會到單個計算機(jī)已經(jīng)無法同時處理這么多數(shù)據(jù)了,我們需要多臺計算機(jī)一起協(xié)作,是時候放出MapReduce這個大招了。
我個人在查閱一些資料、進(jìn)行一些實(shí)踐以后,認(rèn)為MapReduce的技術(shù)可以簡單地用四字訣來總結(jié):分、變、洗、合,分別代表“切分”、“變換”、“洗牌”、“合并”四個步驟:
下面來看如何用四字訣解決大數(shù)據(jù)撲克牌問題。
1、切分:把輸入數(shù)據(jù)切分成多份
既然單個“人型計算機(jī)”無法完全處理完所有的撲克,那么我們就把撲克牌隨機(jī)分成多份,每份撲克牌由一個“人型計算機(jī)”來處理,個數(shù)不超過單個計算機(jī)的處理上限,而且盡量讓每份的數(shù)量比較平均。
這里我們要講一下角色分工的問題,多臺計算機(jī)合作,肯定要有角色分工,我們把負(fù)責(zé)數(shù)據(jù)切分的“人型計算機(jī)”可以理解為“指揮官”,“指揮官”一般只有一個(在實(shí)際中可能有多個),統(tǒng)籌調(diào)度之類的工作都?xì)w他管。負(fù)責(zé)執(zhí)行具體運(yùn)算任務(wù)的“人型計算機(jī)”則是“計算兵”,“計算兵”按照承擔(dān)的任務(wù)不同分為“變計算兵”和“合計算兵”,前者負(fù)責(zé)第二步“變換”,后者負(fù)責(zé)最后一步“合并”。
“計算兵”的總數(shù)當(dāng)然是多多益善,但“變計算兵”和“合計算兵”各自所占的比例并不固定,可以根據(jù)數(shù)據(jù)的多少和運(yùn)算的效率進(jìn)行調(diào)整。當(dāng)兵力不夠的時候,一個計算兵有可能承擔(dān)兩種角色,“指揮官”同時也有可能擔(dān)任“計算兵”,因?yàn)樵趯?shí)際情況中一臺計算機(jī)可以有多個進(jìn)程承擔(dān)多個任務(wù),即理論上講一個計算機(jī)可以分飾多角。
“指揮官”在切分撲克牌之前,會先分配好“變計算兵”和“合計算兵”的數(shù)量,然后根據(jù)“變計算兵”的數(shù)量把撲克拆分成相應(yīng)的份數(shù),將每份撲克分給一個“變計算兵”,然后進(jìn)入下一步。
2、變換:把每條輸入數(shù)據(jù)做映射變換(也就是MapReduce中的Map)
每一個“變計算兵”都要對自己分得的每一張撲克牌按照相同的規(guī)則做變換,使得后續(xù)的步驟中可以對變換后的結(jié)果做處理。這種變換可以是加減乘除等數(shù)學(xué)運(yùn)算,也可以是對輸入數(shù)據(jù)的結(jié)構(gòu)的轉(zhuǎn)換。例如對于我們這個撲克牌問題來講,目的是為了計數(shù),所以可以將撲克牌轉(zhuǎn)換為一種計算機(jī)更容易處理的數(shù)值結(jié)構(gòu):將每張撲克牌上貼一張小便簽,這條小便簽上寫明了其個數(shù)為1。

我們把這種貼了標(biāo)簽的撲克牌叫做變種撲克牌。當(dāng)在后續(xù)的步驟中統(tǒng)計牌型個數(shù)時,只需要把每個標(biāo)簽上的數(shù)字加起來就可以。有的朋友肯定會好奇為什么不讓每個“計算兵”直接統(tǒng)計各自的所有牌型的撲克的個數(shù),這是因?yàn)檫@種“映射變換”運(yùn)算的本質(zhì)在于將每張撲克牌都進(jìn)行同一種相同規(guī)則的變換,統(tǒng)計個數(shù)的工作要留在最后一步完成。嚴(yán)格的流水化操作,會讓整體的效率更高,而且變換的規(guī)則要根據(jù)具體問題來制定,更容易適配不同種類的計算。
3、洗牌:把變換后的數(shù)據(jù)按照一定規(guī)則分組
變換的運(yùn)算完成之后,每個“變計算兵”要將各自的變種撲克牌按照牌型分成多個小份,每個小份要最終被一個指定的“合計算兵”進(jìn)行結(jié)果合并統(tǒng)計,這個過程就是“洗牌”,是“變計算兵”將變換后的撲克牌按照規(guī)則分組并分配給指定的“合計算兵”的過程。

洗牌分兩個階段,第一階段是每個“變計算兵”將變種撲克牌按照一定的規(guī)則分類,分類的規(guī)則取決于每個“合計算兵”的統(tǒng)計范圍,分類的個數(shù)取決于“合計算兵”的個數(shù)。如上圖所示,假設(shè)有3個“合計算兵”分別負(fù)責(zé)不同范圍的牌型的統(tǒng)計,那么“變計算兵”需要根據(jù)每個“合計算兵”負(fù)責(zé)的牌型將自己的變種撲克牌分成3個小份,每份交給對應(yīng)的“合計算兵”。
洗牌的第二階段,“合計算兵”在指揮官的指揮下,去各個“變計算兵”的手中獲取屬于他自己的那一份變種撲克牌,從而使得牌型相同的撲克牌只會在一個“合計算兵”的手上。洗牌的意義在于使相同牌型的變種撲克牌匯聚在了一起,以便于統(tǒng)計。
4、合并:將洗牌后的數(shù)據(jù)進(jìn)行統(tǒng)計合并(也就是MapReduce中的Reduce)
“合計算兵”將手中的變種撲克牌按照相同的計算規(guī)則依次進(jìn)行合并,計算規(guī)則也需要根據(jù)具體問題來制定,在這里是對撲克牌上標(biāo)簽的數(shù)值直接累加,統(tǒng)計出最終的結(jié)果。

然后所有的“合計算兵”把自己的計算結(jié)果上交給“指揮官”,“指揮官”匯總后公布最終統(tǒng)計的結(jié)果。
總結(jié)
以上,“分變洗合”四字訣介紹完畢,完整過程如下:

分布式處理技術(shù)在邏輯上并不復(fù)雜,但在具體的實(shí)現(xiàn)過程中會有很多復(fù)雜的過程,譬如“指揮官”如何協(xié)調(diào)調(diào)度所有的“運(yùn)算兵”,“運(yùn)算兵”之間如何通信等等。但對于使用MapReduce來完成計算任務(wù)的程序員來講,這些復(fù)雜的過程是透明的,分布式計算框架會自己去處理這些問題,程序員只需要定義兩種計算規(guī)則:第二步中變換的規(guī)則和第四步中合并的規(guī)則。
正所謂大道至簡,萬變不離其宗,理解了MapReduce就理解了大數(shù)據(jù)分布式處理技術(shù),而理解大數(shù)據(jù)分布式處理技術(shù),也就理解了大數(shù)據(jù)技術(shù)的核心。
作者介紹
盧亮,資深軟件研發(fā)工程師,擅長業(yè)務(wù)系統(tǒng)建模與架構(gòu)分析,在分布式架構(gòu)和大數(shù)據(jù)技術(shù)方面有深入的理論研究和實(shí)踐經(jīng)驗(yàn)。
個人博客:www.leonlu.cc