作者:Jack47
轉載請保留作者和原文出處
歡迎關注我的微信公眾賬號程序員傑克,兩邊的文章會同步,也可以添加我的RSS訂閱源。
本文是Storm系列之一,主要介紹Storm的架構設計,推薦讀者在閱讀Storm介紹(一)的基礎之上,閱讀這一篇。本文只是作者的讀書筆記,偏重於淺層次的架構介紹,如果想真正理解內部設計時候的權衡,還需要更多的去閱讀Storm源碼。
理解Storm的架構,有助於幫助我們理解大型分布式系統設計中需要解決的問題,以及解決問題的思路,幫助我們更好的進行Storm性能調優化。
架構#
先上一張Storm的架構圖,如果熟悉 GFS和Hadoop的架構,會發現這些系統的架構圖都很類似。
Storm架構圖
各節點的作用##
如果你熟悉Hadoop的話,可以這樣做一下類比:
Hadoop | Storm | 在Storm中發揮的作用|
----------|-------
JobTracker|Nimbus(只有一個)|
- 在集群中分發代碼
- 給Slave機器/supervisor分配任務
- 失敗檢測(failure monitoring)
- 快速失敗(fail fast),無狀態的(可以kill -9)
TaskTracker|Supervisor(有很多個)|
- 監聽分配到自己所在機器的工作
- 根據Nimbus的指示來起停worker進程
- 快速失敗,無狀態的(可以kill -9)
MapReduce任務 | Topology |
- 一直處理消息(直到你kill它)
- 一個運行中的拓撲包含分散在很多機器上運行的多個worker進程
可以看到Nimbus
是調度器,Worker
是Task
的容器,Task
是任務的真正執行者。
啟動拓撲
為了在集群上啟動一個拓撲,需要首先把代碼打包成一個“胖jar包”--必須包含所有的依賴代碼,除了Storm它自身,因為Storm集群會提供。然后在一台安裝了storm命令行的機器上通過storm jar
命令來提交拓撲:
storm jar my-topology-version-with-dependency.jar com.corp.MyTopology arg1 arg2
這個命令會連到Nimbus,上傳jar包。接下來Nimbus會把拓撲的代碼運送到多台不同的機器或者JVM上。只有當拓撲在機器上部署成功了並且在JVM中初始化了之后,才能真正開始處理消息。
Master結點(Master node)
在分布式系統中,調度服務非常重要,它的設計,會直接關系到系統的運行效率,錯誤恢復(fail over),故障檢測(error detection)和水平擴展(scale)的能力。
集群上任務(task)的調度由一個Master
節點來負責。這台機器上運行的Nimbus
進程負責任務的調度。另外一個進程是Storm UI,可以界面上查看集群和所有的拓撲的運行狀態。
從節點(Slave node)
Storm集群上有多個從節點,他們從Nimbus上下載拓撲的代碼,然后去真正執行。Slave
上的Supervisor
進程是用來監督和管理實際運行業務代碼的進程。在Storm 0.9之后,又多了一個進程Logviewer
,可以用Storm UI來查看Slave
節點上的log文件。
在配置文件storm.yaml
中,決定了一台機器上運行幾個worker:
supervisor.slots.ports:
- 6700
- 6701
- 6702
ZooKeeper的作用
ZooKeeper在Storm上不是用來做消息傳輸用的,而是用來提供協調服務(coordination service),同時存儲拓撲的狀態和統計數據。
- ZooKeeper相當於一塊黑板,
Supervisor
,Nimbus
和worker都在上面留下約定好的信息。例如Supervisor
啟動時,會在ZooKeeper上注冊,Nimbus
就可以發現Supervisor
;Supervisor
在ZooKeeper上留下心跳信息,Nimbus
通過這些心跳信息來對Supervisor
進行健康檢測,檢測出壞節點 - 由於Storm組件(component)的狀態信息存儲在ZooKeeper上,所以Storm組件就可以無狀態,可以 kill -9來殺死
- 例如:Supervisors/Nimbus的重啟不影響正在運行中的拓撲,因為狀態都在ZooKeeper上,從ZooKeeper上重新加載一下就好了
- 用來做心跳
- Worker通過ZooKeeper把孩子executor的情況以心跳的形式匯報給Nimbus
- Supervisor進程通過ZK把自己的狀態也以心跳的形式匯報給Nimbua
- 存儲最近任務的錯誤情況(拓撲停止時會刪除)
Storm的容錯(Fault Tolerance)機制#
正如“搭建一個Storm集群”一文介紹的一樣,必須用工具如daemontools
或者monit
來監控Nimbus和Supervisor的后台進程。這樣如果Nimbus
或者Supervisor
進程掛掉,會被daemontools
檢測到,並進行重啟。
Nimbus
和Supervisor
進程被設計成快速失敗(fail fast)的(當遇到異常的情況,進程就會掛掉)並且是無狀態的(狀態都保存在Zookeeper或者在磁盤上)。
最重要的是,worker進程不會因為Nimbus
或者Supervisor
掛掉而受影響。這跟Hadoop是不一樣的,當JobTracker掛掉,所有的任務都會沒了。
-
當Nimbus掛掉會怎樣?
如果Nimbus是以推薦的方式處於進程監管(例如通過supervisord)之下,那它會被重啟,不會有任何影響
否則當Nimbus掛掉后:
- 已經存在的拓撲可以繼續正常運行,但是不能提交新拓撲
- 正在運行的worker進程仍然可以繼續工作。而且當worker掛掉,supervisor會一直重啟worker。
- 失敗的任務不會被分配到其他機器(是Nimbus的職責)上了
-
當一個Supervisor(slave節點)掛掉會怎樣?
如果Supervisor是以推薦的方式處於進程監管(例如通過(supervisord)[supervisord.org/])之下,那它會被重啟,不會有任何影響
否則當Supervisor掛掉: 分配到這台機器的所有任務(task)會超時,Nimbus會把這些任務(task)重新分配給其他機器。
-
當一個worker掛掉會怎么樣?
當一個worker掛掉,supervisor會重啟它。如果啟動一直失敗那么此時worker也就不能和Nimbus保持心跳了,Nimbus會重新分配worker到其他機器
-
Nimbus算是一個單點故障嗎?
如果Nimbus節點掛掉,worker進程仍然可以繼續工作。而且當worker掛掉,supervisor會一直重啟worker。但是,沒有了Nimbus,當需要的時候(如果worker機器掛掉了)worker就不能被重新分配到其他機器了。
所以答案是,Nimbus在“某種程度”上屬於單點故障的。在實際中,這種情況沒什么大不了的,因為當Nimbus進程掛掉,不會有災難性的事情發生
硬件要求##
ZooKeeper###
- 推薦精心設計過的機器,因為ZooKeeper是Storm的瓶頸
- 每個機器使用一個ZK的實例
- 注意因為同一台機器上的其他進程或者虛擬機他們是共享這台機器的,所以可能會影響ZK的性能(來源)
- I/O是ZooKeeper的瓶頸
- 把ZooKeeper的存儲放到自己的磁盤上
- 使用SSD會顯著提升性能
- 正常情況下,Zookeeper的每次寫操作都會同步到磁盤,這就導致了兩次磁盤尋址操作(一次是數據,一次是數據的日志)。當所有的worker都發心跳給ZooKeeper時,可能會顯著影響性能(來源)。
- 需要監控ZooKeeper節點的I/O負載
- 推薦在生產環境上運行的ZooKooper集群有至少3個節點,這樣即使有一個ZooKeeper服務器掛掉了(例如進行維護),也是可以的。
Storm安全性
原始設計Storm時,完全沒有把安全性考慮在內
現在安全性能相關的功能在一步步加進來
Storm 0.9.x版本上的安全問題:
- 沒有驗證機制(authentication),沒有授權機制(authorization)
- 傳輸的數據(例如worker之間)沒有加密
- ZooKeeper上存儲的數據沒有訪問限制
- 如果Nimbus的Thrift端口沒有鎖住,任意的用戶代碼都可以在節點上執行
更多Storm安全性方面的建議見這里
題外話:
在接觸Storm之后,有個問題在我的腦海里升起,國內的大公司,比如Baidu,Ali,騰訊,都是有誕生Storm這類實時計算框架的土壤的,可是為什么沒有做出來呢?
Apache Storm Basic Training
Fault tolerance
如果您看了本篇博客,覺得對您有所收獲,請點擊右下角的“推薦”,讓更多人看到!

