王潤華 毋建軍 侯佳路
北京政法職業(yè)學院信息技術系
分布式實時計算引擎
——Storm研究
王潤華 毋建軍 侯佳路
北京政法職業(yè)學院信息技術系
王潤華(1978)女,碩士,講師,研究方向為移動互聯(lián)網(wǎng)方向。
本文介紹了一種分布式實時計算引擎——Storm,它具有簡單、高性能、高可靠、可伸縮等特點,并且支持廣泛的編程語言。本文不僅介紹了Storm的架構和特性,還結合實例演示了使用Strom進行實時計算的具體過程。
過去十年在數(shù)據(jù)處理(data processing)領域發(fā)生了一場革命,MapReduce,Hadoop和其他相關技術的出現(xiàn),已經(jīng)使數(shù)據(jù)處理系統(tǒng)的存儲能力、計算能力、伸縮能力達到了之前無法想象的高度。但是遺憾的是這些技術是“批處理系統(tǒng)”而不是實時系統(tǒng),實時性也不是這些系統(tǒng)所關心的,然而業(yè)界對實時處理海量數(shù)據(jù)的需求卻越來越強烈,Storm的出現(xiàn)填補了數(shù)據(jù)處理生態(tài)系統(tǒng)(data processing ecosystem)在實時方面的空白。
對于實時處理,典型的傳統(tǒng)方式是手工建立一個由queues和workers組成的網(wǎng)絡。workers處理來自queue的messages,更新數(shù)據(jù)庫(或其他操作),然后生成新的messages發(fā)送給其他的queues做進一步處理。這種方式有以下幾個問題。
(1)繁瑣:需要花大量的時間去配置向哪里發(fā)送messages、部署workers、部署intermediate queues,真正涉及實時處理邏輯代碼所占的比例很小。
(2)脆弱:缺乏完善的故障容錯(f aul ttolerance)機制,在程序運行過程中需要確保每一個worker和queue都是正常運行的。
(3)伸縮性差:系統(tǒng)運行過程中當message的吞吐量超過了單臺物理機的承載能力時,就需要將數(shù)據(jù)分布到更多的機器上去處理,這需要手工重新配置workers以便可以將數(shù)據(jù)分發(fā)新增的機器上,這樣做不僅麻煩還極易出錯。
雖然queues和workers方式在容錯和伸縮方面有很大的缺陷,但是基于消息處理(message processing)的模型卻非常適合作為實時計算的基礎模型,Strom也使用基于消息處理(message processing)的基礎模型。
Storm具有如下幾個主要特點:
極其廣泛的應用場景;
良好的伸縮性;
無消息丟失保證;
穩(wěn)定與可維護性好;
良好的容錯性;
支持廣泛的編程語言;
Storm集群
從表面上看Storm集群與Hadoop集群非常類似,Hadoop集群上運行MapReduce任務而Storm集群運行被稱為Topology的任務,但MapReduce與Topology有著非常大的差別——最關鍵的一點是MapReduce任務最終會結束而Topology一直處理消息,直到被主動結束。
Storm集群架構如圖1所示,Storm集群由一個主節(jié)點(master node)和多個工作節(jié)點(worker node)組成。主節(jié)點上運行著一個被稱為Nimbus的守護進程,它負責在集群中部署代碼、為每個工作節(jié)點分派任務并監(jiān)控任務的執(zhí)行狀態(tài)。每個工作節(jié)點上也運行著一個被稱為Supervisor的守護進程,Supervisor監(jiān)聽分派給該工作節(jié)點的任務,并根據(jù)需要啟動或關閉工作進程(worker processes),每個工作進程負責執(zhí)行一個Topology的子集;每個Topology由分布在多個工作節(jié)點上的多個工作進程共同執(zhí)行。
Nimbus與Supervisors之間通過一個Zookeeper集群來進行協(xié)調(diào)。Nimbus和Supervisor被設計為無狀態(tài)和快速失?。╢ail-fast)的,所有的狀態(tài)信息都保存在Zookeeper集群或本地磁盤中,這意味著Nimbus和Supervisor失敗退出或被結束后重新啟動將不會丟失任何信息,這樣的設計使得Storm非常的穩(wěn)定。
Topology
前面提到Storm任務被稱為Topology,一個Topology實際上是一個由計算邏輯組成的“圖”,“圖”中每個節(jié)點包含計算邏輯,節(jié)點之間的連接指示數(shù)據(jù)如何在節(jié)點間傳播。Storm使用Thrift作為通信中間件,所以可以使用任何Thrift支持的語言來編寫Topology。
圖1 Storm集群架構
Stream
Stream是Storm的核心抽象概念。在Storm中消息被稱為元組(tuple),Stream就是一個數(shù)量無限的元組序列,Storm提供了一組原語可以以分布和可靠的方式將一個Stream傳播到另一個Stream,其中Spout和Bolt就其中兩個最基本的原語,用戶程序通過實現(xiàn)Spout和Bolt的接口來定制自己的應用邏輯。Spout是Stream的源,Bolt是一個或多個Stream的消費者,做一些處理,也可能生成新的Stream。一個復雜的應用往往需要多個步驟也就是多個Bolt,Bolt可以做非常多的事情,例如:運行函數(shù)、元組過濾、Stream聚合、Stream join、與數(shù)據(jù)庫對話等。
由Spout和Bolt組成的網(wǎng)絡(圖)既是Topology,而圖中的邊則是Stream,Stream指示元組如何在Spout和Bolt間傳播。Topology中的每個節(jié)點(Spout或Bolt)都是并行執(zhí)行的,用戶可以指定每個節(jié)點的并行度,Storm便會產(chǎn)生相應數(shù)量的子任務在集群上執(zhí)行。
前面提到Topology會一直處理消息,直到被主動結束。Storm會重新分配失敗的任務,此外Strom保證沒有消息會丟失,即使硬件出現(xiàn)故障。
數(shù)據(jù)模型
Strom使用消息即元組(tuple)作為數(shù)據(jù)模型,一個元組可以有多個字段(field),字段的類型可以是字符串或字節(jié)數(shù)組,通過一定的擴展用戶也可以使用自定義的字段類型。
Stream grouping
Stream grouping告訴Topology如何在節(jié)點間傳輸元組。前面提到Spout和Bolt都是并行執(zhí)行的,如圖3所示,如果Bolt A需要向Bolt B發(fā)送元組,那么元組如何在Bolt A的子任務和Bolt B的子任務間傳播呢?傳播策略的不同在有些情況下可能會極大的影響計算結果,Stream grouping就是用來解決這個問題的,我們將在Strom應用實例部分進行詳細的說明。
圓圈代表Spout或Bolt的并行子任務
這里通過一個對單詞計數(shù)的Topol o gy(WordCountTopology)來演示Storm的具體應用方法。代碼如圖4所示,該代碼摘自Storm自身的示例程序,并去掉了對說明用法無關的細節(jié)。
圖2 Topology是由Spouts和Bolts組成的圖
圖3 Topology的執(zhí)行過程
圖4 WordCountTopology代碼
要實現(xiàn)一個Topology最主要的工作就是提供具體的Spout、Bolt (用戶的Spout和Bolt需要實現(xiàn)特定接口或繼承自已有的基類)和他們之間Stream grouping。WordCountTopology有一個Spout和兩個Bolt,Soput引用了已有的一個類RandomSentenceSpout來產(chǎn)生隨機的句子,Bolt SplitSentence將句子拆分成單詞,Bolt WordCount對單詞進行統(tǒng)計。RandomSentenceSpout與SplitSentence之間的Stream grouping類型為Shuffle grouping,即子任務間任意傳播元組,而SplitSentence與WordCount間的Stream grouping類型為Fields grouping,即相同的單詞都傳輸給同一個子任務,這對單詞統(tǒng)計的正確性是非常重要的。
Storm的出現(xiàn)填補了數(shù)據(jù)處理生態(tài)系統(tǒng)(d ata processing ecosystem)在實時方面的空白,同時Storm具有高可靠、伸縮性好、編程模型簡單、支持廣泛的編程語言等特點,極大的簡化了分布式實時系統(tǒng)的開發(fā)。
10.3969/j.issn.1001-8972.2015.06.027