上篇講了存儲(chǔ):MySQL瑞眼、HBase曹抬、ES的特點(diǎn)和區(qū)別恋捆。數(shù)據(jù)時(shí)代只有數(shù)據(jù)的存儲(chǔ)當(dāng)然不夠照皆,如何從數(shù)據(jù)中獲取業(yè)務(wù)需要的信息才能創(chuàng)造價(jià)值,這類工作就需要計(jì)算框架來(lái)完成沸停,現(xiàn)在就來(lái)聊一聊我所看到的計(jì)算框架發(fā)展歷程膜毁。
本文主要介紹離線計(jì)算,下一篇重點(diǎn)講解實(shí)時(shí)計(jì)算愤钾。
離線計(jì)算
MapReduce
Google的三篇論文開(kāi)啟了大數(shù)據(jù)處理的篇章瘟滨,其中MapReduce被各大公司作為數(shù)據(jù)處理的主要方案。MapReduce的思想也是從早期的函數(shù)式編程語(yǔ)言中借鑒而來(lái)绰垂,推廣到了分布式系統(tǒng)中室奏,接觸的東西多了,發(fā)現(xiàn)原來(lái)很多知識(shí)都是相通的劲装。(很多初入IT行業(yè)的新人胧沫,面對(duì)不斷出現(xiàn)的新技術(shù)往往會(huì)比較迷茫,到底該學(xué)哪一個(gè)呢占业,其實(shí)找到一個(gè)自己感興趣的方向绒怨,并努力探索下去,相信慢慢就會(huì)一通百通谦疾,當(dāng)然我也是個(gè)新銀南蹂,個(gè)人觀點(diǎn),僅供參考^ ^)
傳統(tǒng)的數(shù)據(jù)處理方式通常是將數(shù)據(jù)導(dǎo)入至專門的數(shù)據(jù)分析工具中念恍,這樣會(huì)面臨兩個(gè)問(wèn)題:1六剥、如果源數(shù)據(jù)非常大時(shí),往往數(shù)據(jù)的移動(dòng)就要花費(fèi)較長(zhǎng)時(shí)間峰伙。2疗疟、傳統(tǒng)的數(shù)據(jù)處理工具往往是單機(jī)模型,面對(duì)海量數(shù)據(jù)時(shí)瞳氓,數(shù)據(jù)處理的時(shí)間也是一個(gè)很大的問(wèn)題策彤。
MapReduce是離線批量計(jì)算的代表,采用移動(dòng)計(jì)算優(yōu)于移動(dòng)數(shù)據(jù)的理念,計(jì)算任務(wù)通常直接在HDFS的datanode上運(yùn)行店诗,這樣避免了數(shù)據(jù)的移動(dòng)(當(dāng)然reduce階段還是需要節(jié)點(diǎn)間傳輸數(shù)據(jù))裹刮,并且采用并行計(jì)算的方式,大大減少了數(shù)據(jù)處理時(shí)間庞瘸。
如圖所示捧弃,MR模型將數(shù)據(jù)切分成大小相同的數(shù)據(jù)塊,分別在對(duì)應(yīng)的數(shù)據(jù)節(jié)點(diǎn)上啟動(dòng)map任務(wù)恕洲,map任務(wù)并行讀取HDFS上的數(shù)據(jù)塔橡,根據(jù)reduce任務(wù)的個(gè)數(shù)將結(jié)果寫入不同的臨時(shí)文件中,map任務(wù)計(jì)算完畢之后霜第,reduce任務(wù)從map節(jié)點(diǎn)處拉取自己負(fù)責(zé)處理的數(shù)據(jù)葛家,并輸出最終結(jié)果。
wordcount例子:
拿wordcount例子舉例泌类,map任務(wù)讀取自身負(fù)責(zé)的數(shù)據(jù)癞谒,統(tǒng)計(jì)詞頻后,中間結(jié)果發(fā)送到對(duì)應(yīng)的reduce節(jié)點(diǎn)刃榨,reduce節(jié)點(diǎn)負(fù)責(zé)統(tǒng)計(jì)最終的詞頻結(jié)果弹砚。
MR結(jié)合HDFS通過(guò)并行計(jì)算的方式,很大程度上解決了我們對(duì)數(shù)據(jù)存儲(chǔ)枢希、計(jì)算的需求桌吃,但是大家并不滿足于現(xiàn)狀,慢慢大家發(fā)現(xiàn)了MR依然存在一些問(wèn)題苞轿。
1.API較單一茅诱,對(duì)復(fù)雜的迭代計(jì)算并不友好
下面我們來(lái)看一個(gè)解方程的例子:
如圖,上過(guò)初中的人一眼都能看出X=1搬卒,但是計(jì)算機(jī)不會(huì)因式分解呀瑟俭,那如何利用計(jì)算機(jī)思想來(lái)求解方程呢?
首先契邀,我們需要將方程轉(zhuǎn)換(圖中紅色部分)摆寄,將其看成一個(gè)級(jí)數(shù),并且保證該級(jí)數(shù)收斂坯门。
然后微饥,在該級(jí)數(shù)收斂區(qū)間假設(shè)一個(gè)初始值,這里我們選取了X=1.5古戴,代入方程右端欠橘,求出新的X值。
最后允瞧,將新的X值不斷的進(jìn)行迭代简软,當(dāng)?shù)贙+1次和第K次的結(jié)果的差值小于我們預(yù)先定義好的閾值時(shí),我們可以認(rèn)為此時(shí)的X值已經(jīng)無(wú)限接近于真實(shí)值述暂,計(jì)算結(jié)束痹升。
對(duì)計(jì)算機(jī)解決數(shù)學(xué)計(jì)算感興趣的同學(xué)可以復(fù)習(xí)一下線性代數(shù)和數(shù)值分析
這里我們可以看到,計(jì)算機(jī)求解方程需要多次迭代畦韭,如果用MR實(shí)現(xiàn)疼蛾,每一次迭代都要啟動(dòng)一次MR任務(wù),這僅僅還只是一個(gè)最簡(jiǎn)單的例子艺配,當(dāng)面對(duì)數(shù)據(jù)挖掘這類涉及到比較復(fù)雜的組合計(jì)算時(shí)察郁,采用MR效率就顯得比較低下了。
2.MR任務(wù)不能有效的利用內(nèi)存
map任務(wù)在處理數(shù)據(jù)后转唉,會(huì)根據(jù)reduce的個(gè)數(shù)皮钠,生成對(duì)應(yīng)個(gè)數(shù)中間文件,這些文件保存在磁盤上赠法,map計(jì)算完成后reduce將文件fetch過(guò)來(lái)進(jìn)行匯總麦轰。也就是說(shuō)如果采用MR,無(wú)論輸入源數(shù)據(jù)有多少砖织,哪怕內(nèi)存放得下款侵,中間結(jié)果還是需要落盤,而我們知道io是計(jì)算機(jī)中最耗時(shí)的操作侧纯,這也是造成MR效率較低的一個(gè)原因新锈。
從上面的介紹可以看出MR存在兩個(gè)缺點(diǎn):
1.無(wú)論源數(shù)據(jù)有多少,shuffle過(guò)程的中間數(shù)據(jù)都需要落盤眶熬,效率較低妹笆,不能很好的利用內(nèi)存。
2.MapReduce只提供了map和reduce函數(shù)聋涨,api不夠友好晾浴,編寫代碼時(shí),首先都需要將計(jì)算思想轉(zhuǎn)化成MapReduce模型牍白,非常反人類(寫過(guò)MR的應(yīng)該非常有感觸)脊凰,而且稍微復(fù)雜點(diǎn)的計(jì)算需要多次迭代(尤其現(xiàn)在都在提人工智能,深度學(xué)習(xí)茂腥,這些都是比較復(fù)雜的邏輯計(jì)算)狸涌,迭代啟動(dòng)任務(wù)也有較大的開(kāi)銷。
Spark
Spark對(duì)這兩點(diǎn)進(jìn)行了優(yōu)化最岗,Spark也是一個(gè)批量計(jì)算框架帕胆,我們來(lái)看一下Spark的job邏輯圖:
Spark的將數(shù)據(jù)抽象成RDD,RDD:彈性分布式數(shù)據(jù)集(Resilient Distributed Datasets)般渡,這是一種分布式的內(nèi)存抽象懒豹,允許在大型集群上執(zhí)行基于內(nèi)存的計(jì)算芙盘,與此同時(shí)還保持了MapReduce等數(shù)據(jù)流模型的容錯(cuò)特性。RDD可以常駐的內(nèi)存的屬性脸秽,大大簡(jiǎn)化了迭代計(jì)算所需的開(kāi)銷儒老,Spark任務(wù)可以立馬利用上一次計(jì)算出來(lái)的RDD來(lái)進(jìn)行下次迭代。
Spark不僅僅提供Map和Reduce函數(shù)记餐,還提供了額外的api驮樊,比如join,圖中我們看到數(shù)據(jù)源data1和data2在中間處進(jìn)行了join片酝,豐富的api大大簡(jiǎn)化了編碼邏輯囚衔,開(kāi)發(fā)更高效(更詳細(xì)api的可以在Spark官網(wǎng)了解)。
RDD優(yōu)化:
需要注意的是內(nèi)存不夠用時(shí)RDD也可以采用磁盤作為其第二存儲(chǔ)介質(zhì)雕沿,而且如果計(jì)算中包含shuffle過(guò)程练湿,為了保證容災(zāi),shuffle處的RDD也是需要落盤的审轮。
上圖中我們可以看到任務(wù)被劃分為3個(gè)stage鞠鲜,這里簡(jiǎn)單解釋一下stage的意義,如果采用MR的運(yùn)行方式断国,每個(gè)partition都啟動(dòng)一個(gè)task贤姆,stage1應(yīng)該啟動(dòng)6個(gè)task,因?yàn)镽DD需要存放在內(nèi)存(內(nèi)存不夠時(shí)放磁盤)稳衬,這樣來(lái)看開(kāi)銷還是很大的霞捡,而且上下游task的RDD傳輸也會(huì)占用不小的開(kāi)銷。
Spark為了提高效率薄疚,采取了如下優(yōu)化:當(dāng)下游的RDD和上游的RDD是NarrowDependency時(shí)(也就是上游partition和下游partition是1對(duì)1碧信,或n對(duì)1的關(guān)系,不涉及shuffle邏輯街夭,比如map砰碴,flatmap等操作),將這些RDD放在一個(gè)task里面執(zhí)行板丽,大大減少了計(jì)算時(shí)所需的內(nèi)存開(kāi)銷呈枉,也減少了網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,詳細(xì)可以參考埃碱。(很多計(jì)算框架都有采用這種優(yōu)化猖辫,比如Flink)
總結(jié)一下Spark的優(yōu)點(diǎn):
1.它不止提供了map和reduce邏輯,還提供了額外的api砚殿,更好的支持了復(fù)雜的迭代計(jì)算啃憎,如:groupby、join等函數(shù)似炎。
2.更好的利用內(nèi)存:內(nèi)存夠用的情況下辛萍,數(shù)據(jù)直接在內(nèi)存進(jìn)行處理悯姊,減少數(shù)據(jù)落盤次數(shù),提高計(jì)算效率贩毕。
這時(shí)候問(wèn)題來(lái)了:那既然Spark這么好挠轴,是不是Spark可以完全取代MR了?
答:也沒(méi)有那么絕對(duì)耳幢,任何東西都有它存在的理由,都有它發(fā)光發(fā)熱的地方欧啤,比如當(dāng)數(shù)據(jù)量非常大睛藻,Spark內(nèi)存放不下的時(shí)候,數(shù)據(jù)也是需要落盤的邢隧。對(duì)海數(shù)據(jù)簡(jiǎn)單清洗店印,排序時(shí),Spark的性能并不一定就比MR好倒慧,所以還需要看具體的業(yè)務(wù)按摘。
而且前兩年大家都在說(shuō)Spark將會(huì)取代Hadoop,與其說(shuō)是取代Hadoop纫谅,倒不如說(shuō)Spark有可能取代MapReduce炫贤,因?yàn)镾park自身是沒(méi)有存儲(chǔ)功能的,數(shù)據(jù)源往往依賴HDFS存儲(chǔ)付秕。
MR和Spark采用批量的方式解決離線計(jì)算業(yè)務(wù)兰珍,那想象一下另一些場(chǎng)景:在金融業(yè)務(wù)中,我們希望能夠馬上檢測(cè)到有問(wèn)題的賬單饥追,或者我們希望實(shí)時(shí)得到系統(tǒng)狀態(tài)的統(tǒng)計(jì)信息变泄,若采用批量框架巾表,很難及時(shí)的得到反饋結(jié)果,這時(shí)就需要實(shí)時(shí)計(jì)算唠摹。
下篇重點(diǎn)講解目前流行的實(shí)時(shí)計(jì)算框架和它們各自的特點(diǎn)。