擴(kuò)展MapReduce架構(gòu)的一種嘗試
假設(shè)有這樣一個(gè)游戲,一個(gè)人來出加減乘除的題目給很多小朋友來做,對每一個(gè)小朋友,給他出一道題目,然后讓他算好后給你報(bào)告答案,你再給他出一道題目,周而復(fù)始如此。如果有十個(gè)小朋友在算,還可以欣賞小朋友抓耳撓腮的樣子;如果有一百個(gè)小朋友,每個(gè)人都在爭著表現(xiàn),叫嚷著讓出題,這個(gè)人肯定不堪重負(fù);如果有成千上萬個(gè)小朋友呢?這個(gè)人瘋了。
面對這樣的場景,學(xué)生時(shí)的經(jīng)驗(yàn)是不斷地改進(jìn)和優(yōu)化算法;而工作以后的經(jīng)驗(yàn)是再拽的算法也難以抵擋海量的數(shù)據(jù)或任務(wù),主要還是增加資源,其次才是優(yōu)化算法,兩者可并行。小朋友越多,相應(yīng)地增加出題人的數(shù)量,也可以緩解每個(gè)人的壓力。
與這種場景類似,MapReduce框架也面臨類似的問題。如下圖:

越來越多的task tracker會(huì)讓job tracker很有壓力,以至于task tracker有很多時(shí),job tracker不能及時(shí)響應(yīng)請求,很多task tracker就空閑著資源,等待job tracker的response。Job tracker的壓力與task tracker的資源浪費(fèi)問題導(dǎo)致整個(gè)集群難于擴(kuò)展,對外提供服務(wù)的能力也相當(dāng)下降很多。當(dāng)前Yahoo也受此困擾,正醞釀重構(gòu)MapReduce架構(gòu)。我沒從這個(gè)架構(gòu)看出對現(xiàn)有問題的改善之處,所以自己來試著分析下解決方法。
回頭來看模擬場景,如果把小朋友按班分,每個(gè)班都有一位老師。每位老師從出題人那里得到很多題目,然后讓自己班的小朋友來做。這樣,出題人的壓力在于老師的數(shù)量,老師的壓力在于班里小朋友的數(shù)量。以前小朋友數(shù)量增加帶給出題人的壓力,現(xiàn)在分?jǐn)偟嚼蠋熅蜁?huì)成倍地減少。與之前相比,不同處在于引入了老師這個(gè)角色。
如果以同樣方式解決MapReduce問題,那“老師”的角色應(yīng)該由誰來扮演呢?MapReduce的初衷之一是“盡量移動(dòng)計(jì)算而不是數(shù)據(jù)”。假如數(shù)據(jù)存放于HDFS這樣的文件系統(tǒng)上,移動(dòng)數(shù)據(jù)的成本在于機(jī)器之間的帶寬限制,由此HDFS網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)表示機(jī)器之間數(shù)據(jù)移動(dòng)的等級(jí)。MapReduce的map task會(huì)去訪問HDFS的存儲(chǔ)block,如果block在機(jī)器本地或是與task tracker 在同一rack內(nèi),對執(zhí)行沒有太大影響,否則集群帶寬會(huì)嚴(yán)重影響task執(zhí)行效率。
從上述描述來看,影響task執(zhí)行的***網(wǎng)絡(luò)拓?fù)浞秶莚ack。一般來說,Rack間的網(wǎng)絡(luò)帶寬肯定要比rack內(nèi)的帶寬小。那我們就以rack來作為“老師”的角色。以此假設(shè),我們在每個(gè)rack內(nèi)將某臺(tái)機(jī)器設(shè)為secondary job tracker,負(fù)責(zé)rack內(nèi)task資源的調(diào)度與分發(fā)單位。結(jié)構(gòu)圖如下:

這個(gè)結(jié)構(gòu)有兩種job tracker:Global job tracker與Secondary job tracker。Global JT負(fù)責(zé)跨rack的task分發(fā)與調(diào)度。基本task分配策略是根據(jù)job輸入數(shù)據(jù)的block存儲(chǔ)情況,只分配block在當(dāng)前rack內(nèi)的map task到rack上,分配reduce task 到 map task多的rack上。Secondary JT與Global JT保持著心跳,它管理的map task操作數(shù)據(jù)要么是node-local,要么是rack-local cache 級(jí)別,不會(huì)再有map task跨rack取數(shù)據(jù)的場景,所以分發(fā)策略就很簡單了。
在這個(gè)結(jié)構(gòu)下,client提交job的流程就變成:1. Client上傳job相關(guān)的輸入數(shù)據(jù)到HDFS上,HDFS會(huì)將block幅本存放與不同的data node上,這些data node有在同一個(gè)rack內(nèi),也有跨rack存在的。2. job提交到Global JT后,根據(jù)block存儲(chǔ)情況(在哪些rack上存在block就往哪些rack的Secondary JT發(fā)送map task,且根據(jù)rack上map task的多少來分發(fā)reduce task)。3. Secondary JT向Global JT匯報(bào)當(dāng)前rack內(nèi)的資源情況,得到那些自己rack內(nèi)的task。4. Secondary JT響應(yīng)本rack內(nèi)的TT 心跳,然后分配適合的task來執(zhí)行。
以rack劃分MapReduce架構(gòu),也是考慮到HDFS與網(wǎng)絡(luò)帶寬情況的結(jié)果。如果每個(gè)rack內(nèi)有15到20臺(tái)機(jī)器,10000臺(tái)機(jī)器差不多可以分布到七八百rack內(nèi)。Global JT與Secondary JT的并發(fā)壓力都不大。這樣的垂直擴(kuò)展只是暫時(shí)解決了部分問題,但沒有從根本上解決job分配程序的壓力。
上述只是我的個(gè)人想法,希望得到各位的指正及建議,謝謝!
【編輯推薦】