分布式离线计算—MapReduce—基础介绍
原文作者:哪有天生的學(xué)霸,一切都是厚積薄發(fā)
原文地址:MapReduce介紹
目錄
場景
MapReduce產(chǎn)生背景
MapReduce功能:
總結(jié)
場景
比如有海量的文本文件,如訂單,頁面點(diǎn)擊事件的記錄,量特別大,單機(jī)版很難搞定,怎么解決海量數(shù)據(jù)的計(jì)算?
求和: 1 + 5 +7 + 3 +4 +9 +3 + 5 +6
MapReduce產(chǎn)生背景
如果讓你統(tǒng)計(jì)日志里面的出現(xiàn)的某個(gè)URL的總次數(shù),讓你自己去寫個(gè)單機(jī)版的程序,寫個(gè)邏輯:無非就是讀這個(gè)文件一行,然后把那個(gè)地方截取出來,截取出來之后,然后可以把它放到一個(gè)HashMap里面,用Map去重,看到一條新的URL ,就把它put進(jìn)去,然后+1,如果下次看到再有就直接+1,沒有就put進(jìn)去,單機(jī)版的話邏輯是很好實(shí)現(xiàn),但是數(shù)據(jù)量一大,你覺得單機(jī)版本還能搞定嗎?
首先2T的文件,你放在單機(jī)上可能存不下來,如果再他多一點(diǎn)呢?比如幾千個(gè)文件,幾十個(gè)T,單機(jī)存都存不下,那么存在哪里-------hdfs上。因?yàn)榉旁贖DFS上可以放很多很多,比如說HDFS上有100個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)上能耐掛載8T的硬盤,那就有800T,800T,你每個(gè)文件存3個(gè)副本的話,你至少也能存100多個(gè)T文件,耗費(fèi)了大概6個(gè)T的空間,但是你一旦放到HDFS上就有一個(gè)問題:你的文件就會被切散了,被切散到很多的機(jī)器上,這個(gè)時(shí)候,你再對它們進(jìn)行統(tǒng)計(jì),這個(gè)時(shí)候,按照原來的邏輯,會不會出現(xiàn)問題?
你的任何一個(gè)節(jié)點(diǎn)上存的是某個(gè)文件的某些塊,假設(shè)你是在那臺機(jī)器上去做統(tǒng)計(jì)的話,你統(tǒng)計(jì)到的永遠(yuǎn)是局部的數(shù)據(jù),那你專門寫一個(gè)客戶端,我的程序運(yùn)行在這個(gè)客戶端上,我去讀數(shù)據(jù),讀一點(diǎn)統(tǒng)計(jì)一點(diǎn),到把整個(gè)文件都讀完了,統(tǒng)計(jì)結(jié)果也就出來了,問題是那樣的話,你的程序又變成了一個(gè)單機(jī)版的,那你的內(nèi)存也就不夠,因?yàn)槟阋谝稽c(diǎn)進(jìn)來統(tǒng)計(jì)一點(diǎn),是不是要保存一些中間數(shù)據(jù),那你可能內(nèi)存也不夠了,而且你因?yàn)槭且粋€(gè)單機(jī)版的程序,所以你的速度是不是也很慢,而且你還要不斷的從網(wǎng)絡(luò)里面去拿那些數(shù)據(jù),也會很慢,所以這個(gè)時(shí)候呢?你專門寫一個(gè)客戶端去做統(tǒng)計(jì),肯定是不合適。
那你是不是應(yīng)該把你的程序分發(fā)到集群的每一臺DN上去做統(tǒng)計(jì),也就是把運(yùn)算往數(shù)據(jù)去移動,而不是把數(shù)據(jù)移動到運(yùn)算,把我的運(yùn)算邏輯移動到數(shù)據(jù)那端去,數(shù)據(jù)在哪里,我就在哪里運(yùn)算,但是這也有一個(gè)問題,因?yàn)?span style="color:#f33b45;">運(yùn)算也變成了一個(gè)分布式的了,你的每一份運(yùn)算結(jié)果都只是局部的結(jié)果,那么這個(gè)時(shí)候也存在問題:
你的代碼怎么實(shí)現(xiàn)分發(fā)到很多機(jī)器上去運(yùn)行,這件事情誰幫你做,如果是要你自己寫程序的話,你是不是得有個(gè)U盤拷你的jar包,一個(gè)計(jì)算一個(gè)計(jì)算的去拷,拷完之后再啟動,每個(gè)機(jī)器都啟動jar,等你啟動最后一臺的時(shí)候,前面那臺已經(jīng)運(yùn)行完了,最后一臺才剛開始啟動,這個(gè)工作你用手動去做是不是不合適啊?所以當(dāng)你把一個(gè)簡單的邏輯,變成這種分布式運(yùn)行的時(shí)候,你發(fā)現(xiàn)很多問題就來了:
我的代碼怎么分發(fā),怎么配置啟動環(huán)境,怎么啟動起來,這個(gè)是不是得有一個(gè)龐大的系統(tǒng)去做,也就是說你應(yīng)該額外開發(fā)這么一個(gè)叫做資源分發(fā)和Java啟動程序這么一個(gè)配置 的系統(tǒng),這個(gè)系統(tǒng)你會嗎?寫得出來嗎?你要是寫的話,是不是還得花很多時(shí)間,你還要寫很多東西,因?yàn)槟悻F(xiàn)在的Java不一定是擅長那個(gè)領(lǐng)域的 ,那這個(gè)耗費(fèi)的代價(jià)就很大了
那個(gè)數(shù)據(jù),比如剛才那個(gè)日志數(shù)據(jù),是放到HDFS上面去了,但是不代表HDFS上的每一臺DN上面都有這一部分?jǐn)?shù)據(jù)里面的內(nèi)容,因?yàn)槲覀冞@個(gè)集群很大,你這個(gè)文件存進(jìn)去的時(shí)候可能只占了其中的30臺節(jié)點(diǎn),其中某30臺節(jié)點(diǎn)上有你這些文件,其他節(jié)點(diǎn)上個(gè)根本就沒有你這些文件,那我們的代碼,運(yùn)行邏輯,最好是放到那30臺上面去做統(tǒng)計(jì),你放到其他的那些機(jī)器上,它可以運(yùn)行,但是它的數(shù)據(jù)必須來源于網(wǎng)絡(luò),是不是效率會比較低,也就是說你的代碼究竟分發(fā)到哪些機(jī)器上去運(yùn)行,是不是也要一個(gè)策略的問題,那么這個(gè)策略是不是也有一定的算法,那么這個(gè)時(shí)候,你為了實(shí)現(xiàn)你那個(gè)簡單的邏輯,就再去開發(fā)這樣一個(gè)系統(tǒng)出來是不是也是很大的開發(fā)量,再考慮一個(gè)問題,假如剛才那兩個(gè)工作你都做完了,你的代碼真的成功的在那30臺機(jī)器上跑起來了,跑起來之后,其中假設(shè)有一臺機(jī)器宕機(jī)了,那么你統(tǒng)計(jì)的那一部分局部數(shù)據(jù)是不是也就沒有了,那個(gè)局部結(jié)果也就沒有了,那個(gè)局部結(jié)果沒有,假設(shè)你有個(gè)匯總的結(jié)果還正確嗎?沒有意義了,也就是說你還得解決一個(gè)問題,就是你時(shí)時(shí)刻刻得卻監(jiān)控著你的程序運(yùn)行情況,那個(gè)節(jié)點(diǎn)正常,哪個(gè)節(jié)點(diǎn)不正常,這個(gè)問題也是很復(fù)雜的,假設(shè)這個(gè)問題 你也解決了,還有一個(gè)問題:
剛才你的邏輯只是統(tǒng)計(jì)出中間結(jié)果,這個(gè)時(shí)候是不是還得匯總啊,匯總就是意味著,你要在那30臺節(jié)點(diǎn)之間結(jié)果里面才能匯總,要么把它們?nèi)空{(diào)到一臺機(jī)器上就能進(jìn)行匯總,但是你調(diào)到一臺機(jī)器上匯總的話,你那一臺機(jī)器的負(fù)載是不是會很高,對吧?假設(shè)我調(diào)到多態(tài)機(jī)器匯總,邏輯就變得復(fù)雜了,比如說,只要是你們那30臺機(jī)器上統(tǒng)計(jì),每臺機(jī)器上的那個(gè)URL有多少條,你又把那個(gè)所有那個(gè)URL的數(shù)據(jù)全部匯總到某個(gè)匯總節(jié)點(diǎn),假如有兩個(gè)URL,哪個(gè)URL分發(fā)到那個(gè)節(jié)點(diǎn)上進(jìn)行匯總,這個(gè)策略是不是也會變得很復(fù)雜了,那你還得去做個(gè)中間數(shù)據(jù)的調(diào)度系統(tǒng),那也很麻煩。
那這樣的話,我們就發(fā)現(xiàn),哪怕是一個(gè)很簡單的東西,你也要把它變成一個(gè)分布式運(yùn)行的程序,是不是面臨很多很多其他的問題,跟我們邏輯無關(guān)的問題,往往這些問題要比解決那個(gè)邏輯要復(fù)雜得多,那么這些問題解決不是我們擅長的,我們大量的普通程序員還沒達(dá)到那些程度,這么復(fù)雜的問題要寫出來是不是很麻煩呢?你不能要求每個(gè)程序員都能達(dá)到那個(gè)功力把,我們不過就是寫個(gè)簡單的邏輯統(tǒng)計(jì)這個(gè)文本里面哪個(gè)URL出現(xiàn)的總次數(shù),很簡單的東西,所以呢,MapReduce才是我們這些普通程序員的福音。
就是說當(dāng)我們面臨海量數(shù)據(jù)處理的時(shí)候,那個(gè)邏輯也許很簡單,但是面臨海量數(shù)據(jù)處理,要我們這個(gè) 邏輯代碼變成分布式運(yùn)行,就會變得很復(fù)雜,而那些很復(fù)雜的事情又不是我們關(guān)心的,我關(guān)心的只是那個(gè)邏輯,那這個(gè)時(shí)候,就有人把你不擅長的而且又必須解決的,而且跟你的邏輯關(guān)系又不大的那些東西全部給封裝起來,那么這個(gè)時(shí)候,我們是不是就直接寫邏輯了,就會MapReduce的框架和Yarn,這兩個(gè)是不是做運(yùn)算的,由這兩個(gè)框架把我們剛才講的那些東西全部封裝起來,這個(gè)就是MapReduce產(chǎn)生的背景,就是這個(gè)問題。
MapReduce功能:
綜上,MapReduce提供了以下的主要
- 數(shù)據(jù)劃分和計(jì)算任務(wù)調(diào)度:
系統(tǒng)自動將一個(gè)作業(yè)(Job)待處理的大數(shù)據(jù)劃分為很多個(gè)數(shù)據(jù)塊,每個(gè)數(shù)據(jù)塊對應(yīng)于一個(gè)計(jì)算任務(wù)(Task),并自動 調(diào)度計(jì)算節(jié)點(diǎn)來處理相應(yīng)的數(shù)據(jù)塊。作業(yè)和任務(wù)調(diào)度功能主要負(fù)責(zé)分配和調(diào)度計(jì)算節(jié)點(diǎn)(Map節(jié)點(diǎn)或Reduce節(jié)點(diǎn)),同時(shí)負(fù)責(zé)監(jiān)控這些節(jié)點(diǎn)的執(zhí)行狀態(tài),并 負(fù)責(zé)Map節(jié)點(diǎn)執(zhí)行的同步控制。
- 數(shù)據(jù)/代碼互定位:
為了減少數(shù)據(jù)通信,一個(gè)基本原則是本地化數(shù)據(jù)處理,即一個(gè)計(jì)算節(jié)點(diǎn)盡可能處理其本地磁盤上所分布存儲的數(shù)據(jù),這實(shí)現(xiàn)了代碼向 數(shù)據(jù)的遷移;當(dāng)無法進(jìn)行這種本地化數(shù)據(jù)處理時(shí),再尋找其他可用節(jié)點(diǎn)并將數(shù)據(jù)從網(wǎng)絡(luò)上傳送給該節(jié)點(diǎn)(數(shù)據(jù)向代碼遷移),但將盡可能從數(shù)據(jù)所在的本地機(jī)架上尋 找可用節(jié)點(diǎn)以減少通信延遲。
- 系統(tǒng)優(yōu)化:
為了減少數(shù)據(jù)通信開銷,中間結(jié)果數(shù)據(jù)進(jìn)入Reduce節(jié)點(diǎn)前會進(jìn)行一定的合并處理;一個(gè)Reduce節(jié)點(diǎn)所處理的數(shù)據(jù)可能會來自多個(gè) Map節(jié)點(diǎn),為了避免Reduce計(jì)算階段發(fā)生數(shù)據(jù)相關(guān)性,Map節(jié)點(diǎn)輸出的中間結(jié)果需使用一定的策略進(jìn)行適當(dāng)?shù)膭澐痔幚?#xff0c;保證相關(guān)性數(shù)據(jù)發(fā)送到同一個(gè) Reduce節(jié)點(diǎn);此外,系統(tǒng)還進(jìn)行一些計(jì)算性能優(yōu)化處理,如對最慢的計(jì)算任務(wù)采用多備份執(zhí)行、選最快完成者作為結(jié)果。
- 出錯(cuò)檢測和恢復(fù):
以低端商用服務(wù)器構(gòu)成的大規(guī)模MapReduce計(jì)算集群中,節(jié)點(diǎn)硬件(主機(jī)、磁盤、內(nèi)存等)出錯(cuò)和軟件出錯(cuò)是常態(tài),因此 MapReduce需要能檢測并隔離出錯(cuò)節(jié)點(diǎn),并調(diào)度分配新的節(jié)點(diǎn)接管出錯(cuò)節(jié)點(diǎn)的計(jì)算任務(wù)。同時(shí),系統(tǒng)還將維護(hù)數(shù)據(jù)存儲的可靠性,用多備份冗余存儲機(jī)制提 高數(shù)據(jù)存儲的可靠性,并能及時(shí)檢測和恢復(fù)出錯(cuò)的數(shù)據(jù)。
總結(jié)
把我們很簡單的運(yùn)算邏輯很方便的擴(kuò)展到海量數(shù)據(jù)的場景下分布式運(yùn)算,所以MapReduce程序?qū)ξ覀兂绦騿T來說很簡單,因?yàn)樗涯切〇|西都給封裝起來了,你只要寫業(yè)務(wù)邏輯,寫業(yè)務(wù)邏輯還不擅長嗎?業(yè)務(wù)邏輯大部分就是處理文本,處理字符串,我們學(xué)的大部分邏輯里面,大部分都是在處理這個(gè)問題:處理文本、處理字符串、查詢數(shù)據(jù)庫是不是得到一些東西啊。查詢一下數(shù)據(jù)庫,處理一下字符串,輸出結(jié)果,而這個(gè)邏輯本身 不用你太多的分布式細(xì)節(jié) ,你只要把邏輯寫出來就可以了,但是你寫MapReduce的時(shí)候,必須要符合人家編程的規(guī)范,你不能你的寫法寫,他按他的寫法寫,每個(gè)人的寫法都不一樣,那MapReduce也沒法給你去分發(fā)和運(yùn)行,所以你也要符合他的規(guī)范,怎樣才算符合規(guī)范呢?就說你的代碼,你的任意一個(gè)邏輯實(shí)現(xiàn)都要分成這么兩個(gè)步驟:
比如說我們統(tǒng)計(jì)日志文件里面,相同URL出現(xiàn)的總次數(shù)如下圖:
例子:
?
總結(jié)
以上是生活随笔為你收集整理的分布式离线计算—MapReduce—基础介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见索引结构—FST
- 下一篇: 分布式离线计算—MapReduce—为什