Author:放翁(文初)
Email:fangweng@taobao.com
Mblog:
weibo.com/fangweng
Blog: http://blog.csdn.net/cenwenchu79/
重要:全文內(nèi)容都是參照這個(gè)源碼地址內(nèi)容所寫,因此兩邊對(duì)著看會(huì)更清晰明了:https://github.com/cenwenchu/beatles
這篇小記主要處于兩方面考慮:首先,希望打破一提到海量數(shù)據(jù)分析,就只有hadoop基礎(chǔ)上的一系列工具,更多的時(shí)候很多企業(yè)需要的是更輕量的設(shè)計(jì)(辦喜酒殺豬殺雞未必都要用一把刀),因此將開放平臺(tái)基礎(chǔ)分析組件重構(gòu)版本beatles的設(shè)計(jì)寫出來,給出更多的思考空間。其次,也是希望推廣一種思想,所有的系統(tǒng),框架設(shè)計(jì)簡(jiǎn)化(可擴(kuò)展),小部件精致化,這樣才能讓很多項(xiàng)目能夠整體靈活,細(xì)節(jié)給力。
這篇小記一共分成4部分,概述,整體設(shè)計(jì),局部設(shè)計(jì),待續(xù)。如果你只想了解個(gè)背景,那么看完概述即可,如果對(duì)于流式分析的大框架設(shè)計(jì)感興趣(看看省略了分布式計(jì)算集群的什么?核心設(shè)計(jì)是怎么樣的),請(qǐng)仔細(xì)看完整體設(shè)計(jì)。如果還對(duì)代碼優(yōu)化有興趣,那請(qǐng)看局部設(shè)計(jì)(細(xì)到代碼功能級(jí)別)。最后留下的待續(xù),將會(huì)增加后續(xù)的一些擴(kuò)展,及同學(xué)看完后提出問題的解答(比較通用的一些問題,例如容災(zāi)啊,啥啥啥很多被認(rèn)為很重要的東西)
07年底開始做開放平臺(tái),當(dāng)時(shí)每天訪問量在4kw左右,考慮到開放平臺(tái)的數(shù)據(jù)透明化需求,開始考慮如何做統(tǒng)計(jì)分析,當(dāng)時(shí)需求是一天出一次結(jié)果即可,因此自己摸索搭建Hadoop迷你集群,開始了分析之路。09年公司調(diào)整加入淘寶開放平臺(tái),當(dāng)時(shí)每天服務(wù)調(diào)用量2億,數(shù)據(jù)分析要求比較散,從服務(wù)的系統(tǒng)數(shù)據(jù)統(tǒng)計(jì)到業(yè)務(wù)趨勢(shì)統(tǒng)計(jì)都有涉及,而且統(tǒng)計(jì)需求變化較多,因此開始籌備自己寫簡(jiǎn)單的統(tǒng)計(jì)抽象模型來規(guī)避MapReduce類,提高適應(yīng)變化的能力,同時(shí)出于簡(jiǎn)化系統(tǒng)設(shè)計(jì)維護(hù)的要求,直接將每日分析數(shù)據(jù)放置到集中服務(wù)器上,每日拉取,切割,分析(統(tǒng)計(jì)分析引擎抽象完成)。2010年開放平臺(tái)基礎(chǔ)體系開始建立,對(duì)于服務(wù)質(zhì)量,應(yīng)用行為,用戶安全都提到了較高的要求上來,分析結(jié)果從原來的統(tǒng)計(jì)分析,擴(kuò)展到了監(jiān)控告警,每日分析轉(zhuǎn)變?yōu)樵隽糠治觯l度1小時(shí)左右),簡(jiǎn)化的任務(wù)調(diào)度模型抽象出來,同時(shí)服務(wù)調(diào)用量增漲到了9億。2011年平臺(tái)數(shù)據(jù)統(tǒng)計(jì)分析及時(shí)性要求更高,同時(shí)開始開放統(tǒng)計(jì)數(shù)據(jù)給外部開發(fā)者(系統(tǒng)可用性和效率要求更高),整體框架和局部設(shè)計(jì)不斷優(yōu)化和改進(jìn),截至今年11月,單日最大服務(wù)調(diào)用量19億,增量統(tǒng)計(jì)實(shí)時(shí)性要求在2分鐘內(nèi)(包含數(shù)據(jù)分析和數(shù)據(jù)產(chǎn)出,低峰期1分鐘,高峰期1分半),系統(tǒng)可用性要求高于99.6%,而投入的服務(wù)器比起動(dòng)則幾十臺(tái)甚至上百上千的Hadoop系統(tǒng)來說,就是一個(gè)迷你集群(一臺(tái)Master實(shí)體機(jī)(16核,16g內(nèi)存),12臺(tái)虛擬機(jī)(虛后5核,8g內(nèi)存,實(shí)際為4臺(tái)實(shí)體機(jī))),每天負(fù)責(zé)600g增量數(shù)據(jù)分析,產(chǎn)出1.5g數(shù)據(jù)。
很多時(shí)候很多開發(fā)人員會(huì)問到說在業(yè)務(wù)和代碼結(jié)構(gòu)優(yōu)化沖突的時(shí)候怎么辦,老板要結(jié)果,而程序員要的是看起來不惡心的代碼,但很多時(shí)候,我們就是在摸索中做事。上面描述的背景就好比開始買的是件夏天穿的短袖,然后天氣不斷變冷,開始給短袖加袖子,然后在身上貼補(bǔ)丁,但最后真的要到冬天的時(shí)候,應(yīng)該怎么辦,在秋天和冬天之間,作為核心代碼負(fù)責(zé)人,就應(yīng)該保證系統(tǒng)可用性的情況下做好另一手準(zhǔn)備(簡(jiǎn)單來說,時(shí)間不是別人給的,而是自己給的,天晴補(bǔ)漏,雨天不愁)。因此年末的兩周將2年中斷斷續(xù)續(xù)走過的路,重新整理了一遍,取名為beatles(甲殼蟲),因?yàn)榧讱はx雖小,但聚集起來能夠吃掉一大片葉子(業(yè)務(wù)系統(tǒng)各種需要分析的數(shù)據(jù)),因此這個(gè)框架首先是個(gè)很小的內(nèi)核(希望有更多擴(kuò)展和參與者),其次不是一個(gè)從頭開始的項(xiàng)目,而是一個(gè)兩年多斷斷續(xù)續(xù)演進(jìn)產(chǎn)品的積累。
Beatles不是一個(gè)萬能的技術(shù)產(chǎn)品,它出生和發(fā)展就為它適合的場(chǎng)景做了定義,因此使用和擴(kuò)展的時(shí)候需要明確的了解是否合適,避免勿用,下面兩個(gè)圖會(huì)大志說一下它的特點(diǎn)和適用場(chǎng)景。

上面這張圖左邊部分是Beatles可以局部犧牲的,右邊部分是場(chǎng)景要求的。由于是對(duì)流式數(shù)據(jù)的增量分析,因此對(duì)于歷史數(shù)據(jù)的全量挖掘無能為例(這部分完全可以用Hadoop這種離線分析系統(tǒng)來做)。數(shù)據(jù)精確性要求所有數(shù)據(jù)在分析的任何一個(gè)環(huán)節(jié)都要做好保護(hù)(數(shù)據(jù)輸入,分析過程,數(shù)據(jù)輸出),而這種強(qiáng)完整性要求勢(shì)必會(huì)使得系統(tǒng)的效率和可用性降低(和右邊實(shí)時(shí)性矛盾),因此會(huì)被放低一些要求(類似于計(jì)費(fèi)結(jié)算等就直接一天走一次分析即可)。在左面所看重的三個(gè)部分大致分布的場(chǎng)景為:監(jiān)控告警(業(yè)務(wù),系統(tǒng),用戶,平臺(tái)透明化),業(yè)務(wù)即時(shí)分析對(duì)比(ABtest),系統(tǒng)灰度發(fā)布對(duì)比,用戶實(shí)時(shí)統(tǒng)計(jì)展示(非金額等數(shù)據(jù)一致性要求較高的內(nèi)容展示)。
要滿足上面所說的場(chǎng)景,實(shí)時(shí)流式數(shù)據(jù)分析需要做哪些功能?


Beatles的任務(wù)調(diào)度十分簡(jiǎn)單,遵循兩個(gè)原則:1.按需分配(Slave的多少及Slave自身執(zhí)行任務(wù)的快慢自然促成的分配方式)2.任務(wù)粒度細(xì)化,粗暴簡(jiǎn)單的任務(wù)重置(通過透明化監(jiān)控任務(wù)可能出現(xiàn)的問題,避免集群陷入一個(gè)任務(wù)的糾結(jié)中)。優(yōu)勢(shì):簡(jiǎn)單,高效,易擴(kuò)展(Slave隨時(shí)來,隨時(shí)走)。劣勢(shì):對(duì)于任務(wù)執(zhí)行可控度較弱(通過任務(wù)細(xì)粒度和粗暴重置狀態(tài)的方式來降低風(fēng)險(xiǎn),增加的只是節(jié)點(diǎn)重復(fù)計(jì)算的浪費(fèi)可能性)。

master處理流程
可以看到Master整體就兩部分工作,對(duì)內(nèi)部任務(wù)的管理維護(hù),對(duì)外部slave請(qǐng)求的處理(請(qǐng)求獲取任務(wù),返回處理后的結(jié)果(Slave也可以不返回結(jié)果,根據(jù)Job定義來判斷,防止Master變重))。Master單點(diǎn)并不可怕,只要遵循兩個(gè)原則:現(xiàn)場(chǎng)可快速恢復(fù),分析流程可追趕。因此做到Master所有狀態(tài)定期外移和實(shí)時(shí)監(jiān)控,即可滿足這種簡(jiǎn)單的Master可用性需求。

slave處理流程
Slave更為單純,整個(gè)生命周期就是獲取任務(wù),分析任務(wù),返回任務(wù)結(jié)果的一個(gè)環(huán),內(nèi)置一個(gè)分析引擎和交互組件,根據(jù)任務(wù)的定義來無差別化的處理各種分析工作(Job定義了數(shù)據(jù)的輸入來源,輸出目標(biāo)地址,分析規(guī)則)。Slave的設(shè)計(jì)主要考慮如何做到無業(yè)務(wù)規(guī)則侵入和數(shù)據(jù)來源限制,滿足了這些需求的情況下才能夠?qū)崿F(xiàn)節(jié)點(diǎn)處理無差別性,各種分析任務(wù)可以跑在一個(gè)集群上(實(shí)現(xiàn)計(jì)算節(jié)點(diǎn)可復(fù)用)。
任務(wù)抽象設(shè)計(jì)比較簡(jiǎn)單,主要結(jié)合任務(wù)調(diào)度設(shè)計(jì),實(shí)現(xiàn)計(jì)算節(jié)點(diǎn)的無差別化。

Job是一類分析的定義(例如對(duì)gc的日志分析,對(duì)服務(wù)調(diào)用日志分析可以定義為兩個(gè)Job),Job中的Task表示對(duì)于這一類數(shù)據(jù)分析再次拆分任務(wù),來分解海量數(shù)據(jù)處理,Task中繼承了Job中的輸入和輸出,支持多種模式的數(shù)據(jù)來源和數(shù)據(jù)輸出。Rule就是分析統(tǒng)計(jì)模型抽象部分主要分成:Alias(對(duì)于分析數(shù)據(jù)的列別名定義),Entry的MapReduce的定義,Report是Entry整合成用戶可接受的Report的定義。
統(tǒng)計(jì)模型抽象主要分為兩部分:統(tǒng)計(jì)模型抽象和統(tǒng)計(jì)流程抽象。統(tǒng)計(jì)模型抽象就是將MapReduce的Key-Value統(tǒng)計(jì),轉(zhuǎn)化成為傳統(tǒng)意義上的報(bào)表結(jié)構(gòu)。
分析的輸入:(弱業(yè)務(wù)含義的大表)
c1,c2,c3,c4,c5,c6
c1,c2,c3,c4
c1,c2,c3,c4,c5,c6,c7
……
MapReduce可以處理的:

如下圖,傳統(tǒng)報(bào)表的一行可以看作是多個(gè)相同key但不同統(tǒng)計(jì)字段組合的結(jié)果。

例如:輸入的數(shù)據(jù)結(jié)構(gòu)如下:
服務(wù)名稱,服務(wù)類型,服務(wù)上行數(shù)據(jù)流量,服務(wù)處理結(jié)果(錯(cuò)誤碼),服務(wù)耗時(shí)
真實(shí)日志如下:(分隔符可在分析時(shí)指定,這里用逗號(hào)作演示)
taobao.user.get,read,100,0,20
taobao.product.add,write,1000,0,50
……
那么定制如下MapReduce組合:
Key:服務(wù)名稱,Value:服務(wù)上行數(shù)據(jù)流量總和。
Key:服務(wù)名稱,Value:服務(wù)耗時(shí)總和。
Key:服務(wù)名稱,Value:服務(wù)平均耗時(shí)。
Key:服務(wù)名稱,Value:服務(wù)最大耗時(shí)。
Key:服務(wù)名稱,Value:服務(wù)最小耗時(shí)。
那么將這些MapReduce處理后的Key-value在組合一次就可以得到:
Key:服務(wù)名稱,Value:服務(wù)上行數(shù)據(jù)流量總和,服務(wù)耗時(shí)總和,服務(wù)平均耗時(shí),服務(wù)最大耗時(shí),服務(wù)最小耗時(shí)。
簡(jiǎn)單來說其實(shí)就是類似于SQL中的Groupby的方式,將一堆<key,value> groupby key。
分析流程抽象如下:

分析流程抽象
流程中可以擴(kuò)展的在第三步和第四步,第三步影響了Key的生成(當(dāng)簡(jiǎn)單的列組合成字符串無法滿足生成key的情況下可擴(kuò)展),第四步影響value的生成。(當(dāng)map的value生成以及Reduce無法滿足需求的情況下可擴(kuò)展),要使用min,max…以外的reduce,可以直接在ReduceClass中作處理,然后使用plain輸出實(shí)現(xiàn)。
這種流程比傳統(tǒng)的MapReduce的寫法好處在于可以對(duì)輸入只讀取一次(海量的日志文件為了多種條件分析,反復(fù)讀取本身就是最大的損耗)。可以看到在文件IO操作上,不會(huì)隨著分析模型配置的增多而增長(zhǎng),中間數(shù)據(jù)也不會(huì)隨著報(bào)表組合的不同而過快膨脹(只要報(bào)表復(fù)用Entry足夠多)。

角色定義
Beatles內(nèi)部業(yè)務(wù)組件如上圖。
Master包含兩個(gè)子組件,JobManager用于管理任務(wù),MasterConnector用于與Slave通信。
Slave包含三個(gè)組件,SlaveConnector用于與服務(wù)端通信,Analysis
Engine用于數(shù)據(jù)分析,JobResultMerger可選,用于在客戶端分擔(dān)服務(wù)端匯總結(jié)果的壓力,同時(shí)讓Slave可以多線程并行執(zhí)行任務(wù)。(當(dāng)然單機(jī)可以跑多個(gè)Slave的實(shí)例)。
Job&Task已經(jīng)提到過用于任務(wù)抽象,支持Slave的Analysis Engine的分析無差別性。
Input&output用于擴(kuò)展整個(gè)框架的各種數(shù)據(jù)來源,例如job構(gòu)建的來源,job的輸入和輸出等。

整體流程
1.
Master利用jobManager通過JobBuilder來構(gòu)建服務(wù)端的任務(wù)集合。
2.
Slave向Master發(fā)起要任務(wù)的請(qǐng)求。
3.
通過Master和Slave的Connector來做交互。
4.
MasterConnector向MasterNode內(nèi)部的事件處理模塊提交事件。
5.
JobManager檢查內(nèi)部任務(wù)狀態(tài)后返回未完成且符合條件的任務(wù)返回給Slave。
6.
SlaveNode收到任務(wù)后調(diào)用內(nèi)部分析引擎并行執(zhí)行任務(wù)分析。
7.
分析引擎獲得任務(wù)的數(shù)據(jù)來源,開始分析數(shù)據(jù)。
8.
如果是多個(gè)任務(wù)并行執(zhí)行,合并同一個(gè)Job的多個(gè)Task的結(jié)果。
9.
導(dǎo)出分析后的結(jié)果
10. 如果是需要匯總到Master的話,利用SlaveConnector返回給Master。
11. MasterConnector獲得返回的分析結(jié)果數(shù)據(jù)。
12. MasterNode類似走事件流程,然后調(diào)度到合并組件合并結(jié)果。
13. 當(dāng)Job任務(wù)全部完成就調(diào)用JobExporter導(dǎo)出數(shù)據(jù)。
代碼結(jié)構(gòu)體系:sourcecode:(https://github.com/cenwenchu/beatles)

整體包結(jié)構(gòu)
整個(gè)項(xiàng)目?jī)?nèi)容不多,根據(jù)包名的前綴可以發(fā)現(xiàn)主要分成兩塊:node,Statistics。前者是任務(wù)調(diào)度及任務(wù)抽象,后者是統(tǒng)計(jì)分析模型抽象。
Config中是多個(gè)角色各自的config定義,同時(shí)這些config會(huì)在一個(gè)實(shí)體里傳播,例如MasterConfig就在MasterNode中傳播到jobManager和MasterConnector組件中,SlaveConfig就在SlaveNode傳播到分析引擎組件和SlaveConnector中。
Node中的結(jié)構(gòu)如下:
Component:對(duì)Node的各個(gè)組件接口的實(shí)現(xiàn)。
Connect:Master與Slave交互的接口定義和實(shí)現(xiàn)。
Io:對(duì)于Job的輸入輸出來源的接口定義和默認(rèn)幾個(gè)實(shí)現(xiàn)。
Event:定義了Master和Slave這樣的Node中需要處理的事件。
Job:任務(wù)抽象定義。
Map,Reduce:支持當(dāng)分析引擎無法滿足的Map,Reduce的情況。(足夠通用的情況下可以被抽象到主框架中)
Operation:定義了Node結(jié)構(gòu)中需要異步處理事件。(因?yàn)楫?dāng)前Node的Event是單線程處理的,因此事件執(zhí)行如果比較消耗,則需要異步后臺(tái)執(zhí)行,或者并行執(zhí)行)
Util包是一些工具類和定義類。
Staitistics是分析引擎接口和實(shí)現(xiàn),其中Data中是分析規(guī)則的抽象。
至此為止,整體的結(jié)構(gòu)設(shè)計(jì)就如上所述了,整體上結(jié)構(gòu)比較簡(jiǎn)單直接,可擴(kuò)展性為了支持分析規(guī)則擴(kuò)展,不同計(jì)算場(chǎng)景擴(kuò)展,效率和可靠性擴(kuò)展。下一個(gè)部分將會(huì)細(xì)化到具體的模塊代碼設(shè)計(jì)上來談優(yōu)化和代碼技巧。
@import url(http://www.tkk7.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);