一、為什么用Storm
storm是一個分布式開源的實時計算系統。可以用來做實時分析、在線機器學習、etl等。
計算速度快,每個節點每秒能處理百萬個 tuples。并且很穩定,容錯性很好保證數據被處理。并且容易設置和操作。
拓撲結構
Nimbus: 主控節點,用于提交任務,分發任務,集群監控等。利用zk進行master選舉,防止單點故障。
supervisor: 負責接收Nimbus提交的任務,分配對應的worker進程。
在物理機上,圖中的 nimbus和suervisor節點一般會對應機器進行部署。
二、基礎概念
Stream
是strom里的數據流的抽象,是一個沒有邊界的tuple隊列
Tuple
storm里數據流的最小單元
Spout
表示storm里數據處理的源頭
Bolt
對stream進行加工處理的邏輯單元,也會經過加工之后發射出一些新的stream
bolt stream里處理可以有多個
Topology
spout和bolt組成的一個邏輯網絡會被打包成topology,topology是storm里的一個邏輯抽象,可以認為是一個job,然后提交到storm集群進行處理。
三、storm topology的并行度
在一個 Storm 集群中,Storm 主要通過以下三個部件來運行拓撲:
工作進程(worker processes)
worker是一個服務進程,從屬于一個特定的topology,一個topology可以設置多個worker執行器(executors)
executor是worker進程分配的一個線程任務(tasks)
executor 執行的內容就是task,task是實際執行過程中數據處理的最小單元,我們程序寫的spout和bolt都會在集群中運行很多個task。
一個supervisor里可以分批多個work,一個work是一個服務進程,work內會啟用多個executor執行task.
一個storm集群會有一個或者多個worker進程來處理各種topology。但是一個worker進程只會運行特定的topology。
一個或者多個executor運行在一個worker下,然后一個executor下會運行多個task,task運行就是spout或者bolt。
圖中是一個包含有兩個 worker 進程的拓撲。其中,藍色的 BlueSpout 有兩個 executor,每個 executor 中有一個 task,并行度為 2;綠色的 GreenBolt 有兩個 executor,每個 executor 有兩個 task,并行度也為2;而黃色的YellowBolt 有 6 個 executor,每個 executor 中有一個 task,并行度為 6,因此,這個拓撲的總并行度就是 2 + 2 + 6 = 10。具體分配到每個 worker 就有 10 / 2 = 5 個 executor。
四、Ack機制
在數據流處理的過程中,strom 如何得知所有bolt都執行成功了,或者說消息可靠性如何保證?
Bolt是可以多個的,從spout輸送tupe開始,到bolt進行處理,產生加工后的新tuple,依次下傳,每級bolt的tuple會對上一個tupe進行錨定,可以簡單的認為記錄下自己的上級tuple,最后會形成一個tupe邏輯樹。
Storm的消息確認機制極為成功,一般的方案會維護系統里的所有tuple樹,并維護著每個tuple的消費狀態,但是成千上萬個tuple樹的存儲空間也是極為龐大的,并且占用的是內存資源。storm它避免了tuple樹的存儲維護,利用異或算法解決了這個問題,節省了內存資源(最多耗費20字節的內存)。
AckerBolt,一個特殊的bolt,用來確認tuple 樹是否成功執行。在一個新的 tuple 樹生成的時候,spout 為每個 tuple 發送一個用于異或的固有 id,acker 會將這些 id 記錄在它的掛起隊列中。每次 executor ack 一個 tuple 的時候,acker 會接收到一個部分校驗和,這個校驗和是 tuple 自身的 id(將其從掛起隊列中清除)和 executor 發送的每個下游 tuple 的 id(放入掛起隊列中)的異或值。
文字看的比較蛋疼,我們直接看下面的圖,用圖說話
步驟細節
tuple樹生成后,AckerBolt 為其維護著一個ackVal, 初始值是 0
- spout 發射消息 T1
- spout 發射消息 T2
- 調用ack方法,告訴AckerBolt T1,T2發送完成,傳遞參數就是其需要確認的消息異或值 param =
T1 ^ T2
,然后AckVal
=T1^T2
(T1^T2 = 0 ^ T1^T2) - bolt1 發射消息 T3,T4,T5
- bolt2 處理完之后,告訴AckerBolt T2 已經處理完畢,傳遞參數
T2
,這時更新AckVal
=(T1^T2) ^ T2
- Bolt-1 調用 AckerBolt 告訴它 T1已經消費成功并成功發送 T3,T4,T5。傳遞參數
T1^T3^T4^T5
,更新AckVal
=(T1^T2) ^ T2^(T1^T3^T4^T5)
- Bolt3 調用 AckerBolt 告訴他 T3,T4,T5已經成功消費,傳遞參數
0^T3^T4^T5
,更新AckVal
=(T1^T2) ^ T2^(T1^T3^T4^T5)^T3^T4^T5
- 計算最終結果
AckVal
=0,該tuple樹,消費完畢。
每個節點要ack的時候,傳遞的ackVal就是自己要確認的消息id之間的異或值
五、storm的容錯性
工作進程(worker)死亡時會發生什么?
工作進程死亡的時候,supervisor 會重新啟動這個進程。如果在啟動過程中仍然一直失敗,并且無法向 Nimbus 發送心跳,Nimbus 就會將這個 worker 重新分配到其他機器上去。
supervisor節點故障
一個節點(集群中的工作節點,非 Nimbus 所在服務器)故障時,該節點上所有的任務(tasks)都會超時,然后 Nimbus 在檢測到超時后會將所有的這些任務重新分配到其他機器上去。
Nimbus節點故障:
nimbus節點用來分發任務,監控集群,當nimbus節點故障的時候,supervisor還會繼續執行接收到任務,對正在執行的任務沒有影響,但是接收不到新的任務,另外當supervisor也出現故障,沒有nimbus能夠進行感知
參考文檔
https://www.cnblogs.com/wuxiang/p/5629138.html
http://ifeve.com/storm-understanding-the-parallelism-of-a-storm-topology/