Storm入門教程:前言
一、實(shí)時(shí)流計(jì)算
互聯(lián)網(wǎng)從誕生的第一時(shí)間起,對世界的最大的改變就是讓信息能夠?qū)崟r(shí)交互,從而大大加速了各個(gè)環(huán)節(jié)的效率。正因?yàn)榇蠹覍π畔?shí)時(shí)響應(yīng)、實(shí)時(shí)交互的需求,軟件行業(yè)除了個(gè)人操作系統(tǒng)之外,數(shù)據(jù)庫(更精確的說是關(guān)系型數(shù)據(jù)庫)應(yīng)該是軟件行業(yè)發(fā)展最快、收益最為豐厚的產(chǎn)品了。記得十年前,很多銀行別說實(shí)時(shí)轉(zhuǎn)賬,連實(shí)時(shí)查詢都做不到,但是數(shù)據(jù)庫和高速網(wǎng)絡(luò)改變了這個(gè)情況。
隨著互聯(lián)網(wǎng)的更進(jìn)一步發(fā)展,從Portal信息瀏覽型到Search信息搜索型到SNS關(guān)系交互傳遞型,以及電子商務(wù)、互聯(lián)網(wǎng)旅游生活產(chǎn)品等將生活中的流通環(huán)節(jié)在線化。對效率的要求讓大家對于實(shí)時(shí)性的要求進(jìn)一步提升,而信息的交互和溝通正在從點(diǎn)對點(diǎn)往信息鏈甚至信息網(wǎng)的方向發(fā)展,這樣必然帶來數(shù)據(jù)在各個(gè)維度的交叉關(guān)聯(lián),數(shù)據(jù)爆炸已不可避免。因此流式處理加NoSQL產(chǎn)品應(yīng)運(yùn)而生,分別解決實(shí)時(shí)框架和數(shù)據(jù)大規(guī)模存儲計(jì)算的問題。
早在7、8年前諸如UC伯克利、斯坦福等大學(xué)就開始了對流式數(shù)據(jù)處理的研究,但是由于更多的關(guān)注于金融行業(yè)的業(yè)務(wù)場景或者互聯(lián)網(wǎng)流量監(jiān)控的業(yè)務(wù)場景,以及當(dāng)時(shí)互聯(lián)網(wǎng)數(shù)據(jù)場景的限制,造成了研究多是基于對傳統(tǒng)數(shù)據(jù)庫處理的流式化,對流式框架本身的研究偏少。目前這樣的研究逐漸沒有了聲音,工業(yè)界更多的精力轉(zhuǎn)向了實(shí)時(shí)數(shù)據(jù)庫。
2010年Yahoo!對S4的開源,2011年twitter對Storm的開源,改變了這個(gè)情況。以前互聯(lián)網(wǎng)的開發(fā)人員在做一個(gè)實(shí)時(shí)應(yīng)用的時(shí)候,除了要關(guān)注應(yīng)用邏輯計(jì)算處理本身,還要為了數(shù)據(jù)的實(shí)時(shí)流轉(zhuǎn)、交互、分布大傷腦筋。但是現(xiàn)在情況卻大為不同,以Storm為例,開發(fā)人員可以快速的搭建一套健壯、易用的實(shí)時(shí)流處理框架,配合SQL產(chǎn)品或者NoSQL產(chǎn)品或者M(jìn)apReduce計(jì)算平臺,就可以低成本的做出很多以前很難想象的實(shí)時(shí)產(chǎn)品:比如一淘數(shù)據(jù)部的量子恒道品牌旗下的多個(gè)產(chǎn)品就是構(gòu)建在實(shí)時(shí)流處理平臺上的。
本教程是一本對storm的基礎(chǔ)介紹手冊,但是我們也希望它不僅僅是一本storm的使用手冊,我們會(huì)在其中加入更多我們在實(shí)際數(shù)據(jù)生產(chǎn)過程的經(jīng)驗(yàn)和應(yīng)用的架構(gòu),最后的目的是幫助所有愿意使用實(shí)時(shí)流處理框架的技術(shù)同仁,同時(shí)也默默的改變這個(gè)世界。
二、Storm特點(diǎn)
Storm是一個(gè)開源的分布式實(shí)時(shí)計(jì)算系統(tǒng),可以簡單、可靠的處理大量的數(shù)據(jù)流。Storm有很多使用場景:如實(shí)時(shí)分析,在線機(jī)器學(xué)習(xí),持續(xù)計(jì)算,分布式RPC,ETL等等。Storm支持水平擴(kuò)展,具有高容錯(cuò)性,保證每個(gè)消息都會(huì)得到處理,而且處理速度很快(在一個(gè)小集群中,每個(gè)結(jié)點(diǎn)每秒可以處理數(shù)以百萬計(jì)的消息)。Storm的部署和運(yùn)維都很便捷,而且更為重要的是可以使用任意編程語言來開發(fā)應(yīng)用。
Storm有如下特點(diǎn):
- 編程模型簡單
在大數(shù)據(jù)處理方面相信大家對hadoop已經(jīng)耳熟能詳,基于Google Map/Reduce來實(shí)現(xiàn)的Hadoop為開發(fā)者提供了map、reduce原語,使并行批處理程序變得非常地簡單和優(yōu)美。同樣,Storm也為大數(shù)據(jù)的實(shí)時(shí)計(jì)算提供了一些簡單優(yōu)美的原語,這大大降低了開發(fā)并行實(shí)時(shí)處理的任務(wù)的復(fù)雜性,幫助你快速、高效的開發(fā)應(yīng)用。
- 可擴(kuò)展
在Storm集群中真正運(yùn)行topology的主要有三個(gè)實(shí)體:工作進(jìn)程、線程和任務(wù)。Storm集群中的每臺機(jī)器上都可以運(yùn)行多個(gè)工作進(jìn)程,每個(gè)工作進(jìn)程又可創(chuàng)建多個(gè)線程,每個(gè)線程可以執(zhí)行多個(gè)任務(wù),任務(wù)是真正進(jìn)行數(shù)據(jù)處理的實(shí)體,我們開發(fā)的spout、bolt就是作為一個(gè)或者多個(gè)任務(wù)的方式執(zhí)行的。
因此,計(jì)算任務(wù)在多個(gè)線程、進(jìn)程和服務(wù)器之間并行進(jìn)行,支持靈活的水平擴(kuò)展。
- 高可靠性
Storm可以保證spout發(fā)出的每條消息都能被“完全處理”,這也是直接區(qū)別于其他實(shí)時(shí)系統(tǒng)的地方,如S4。
請注意,spout發(fā)出的消息后續(xù)可能會(huì)觸發(fā)產(chǎn)生成千上萬條消息,可以形象的理解為一棵消息樹,其中spout發(fā)出的消息為樹根,Storm會(huì)跟蹤這棵消息樹的處理情況,只有當(dāng)這棵消息樹中的所有消息都被處理了,Storm才會(huì)認(rèn)為spout發(fā)出的這個(gè)消息已經(jīng)被“完全處理”。如果這棵消息樹中的任何一個(gè)消息處理失敗了,或者整棵消息樹在限定的時(shí)間內(nèi)沒有“完全處理”,那么spout發(fā)出的消息就會(huì)重發(fā)。
考慮到盡可能減少對內(nèi)存的消耗,Storm并不會(huì)跟蹤消息樹中的每個(gè)消息,而是采用了一些特殊的策略,它把消息樹當(dāng)作一個(gè)整體來跟蹤,對消息樹中所有消息的唯一id進(jìn)行異或計(jì)算,通過是否為零來判定spout發(fā)出的消息是否被“完全處理”,這極大的節(jié)約了內(nèi)存和簡化了判定邏輯,后面會(huì)對這種機(jī)制進(jìn)行詳細(xì)介紹。
這種模式,每發(fā)送一個(gè)消息,都會(huì)同步發(fā)送一個(gè)ack/fail,對于網(wǎng)絡(luò)的帶寬會(huì)有一定的消耗,如果對于可靠性要求不高,可通過使用不同的emit接口關(guān)閉該模式。
上面所說的,Storm保證了每個(gè)消息至少被處理一次,但是對于有些計(jì)算場合,會(huì)嚴(yán)格要求每個(gè)消息只被處理一次,幸而Storm的0.7.0引入了事務(wù)性拓?fù)洌鉀Q了這個(gè)問題,后面會(huì)有詳述。
- 高容錯(cuò)性
如果在消息處理過程中出了一些異常,Storm會(huì)重新安排這個(gè)出問題的處理單元。Storm保證一個(gè)處理單元永遠(yuǎn)運(yùn)行(除非你顯式殺掉這個(gè)處理單元)。
當(dāng)然,如果處理單元中存儲了中間狀態(tài),那么當(dāng)處理單元重新被Storm啟動(dòng)的時(shí)候,需要應(yīng)用自己處理中間狀態(tài)的恢復(fù)。
- 支持多種編程語言
除了用java實(shí)現(xiàn)spout和bolt,你還可以使用任何你熟悉的編程語言來完成這項(xiàng)工作,這一切得益于Storm所謂的多語言協(xié)議。多語言協(xié)議是Storm內(nèi)部的一種特殊協(xié)議,允許spout或者bolt使用標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出來進(jìn)行消息傳遞,傳遞的消息為單行文本或者是json編碼的多行。
Storm支持多語言編程主要是通過ShellBolt, ShellSpout和ShellProcess這些類來實(shí)現(xiàn)的,這些類都實(shí)現(xiàn)了IBolt 和 ISpout接口,以及讓shell通過java的ProcessBuilder類來執(zhí)行腳本或者程序的協(xié)議。
可以看到,采用這種方式,每個(gè)tuple在處理的時(shí)候都需要進(jìn)行json的編解碼,因此在吞吐量上會(huì)有較大影響。
- 支持本地模式
Storm有一種“本地模式”,也就是在進(jìn)程中模擬一個(gè)Storm集群的所有功能,以本地模式運(yùn)行topology跟在集群上運(yùn)行topology類似,這對于我們開發(fā)和測試來說非常有用。
- 高效
用ZeroMQ作為底層消息隊(duì)列, 保證消息能快速被處理。