一個完整的 Storm 流處理程序被稱爲 Storm topology(拓撲)。它是一個是由 Spouts
和 Bolts
經過 Stream
鏈接起來的有向無環圖,Storm 會保持每一個提交到集羣的 topology 持續地運行,從而處理源源不斷的數據流,直到你將主動其殺死 (kill) 爲止。html
Stream
是 Storm 中的核心概念。一個 Stream
是一個無界的、以分佈式方式並行建立和處理的 Tuple
序列。Tuple 能夠包含大多數基本類型以及自定義類型的數據。簡單來講,Tuple 就是流數據的實際載體,而 Stream 就是一系列 Tuple。git
Spouts
是流數據的源頭,一個 Spout 能夠向不止一個 Streams
中發送數據。Spout
一般分爲可靠和不可靠兩種:可靠的 Spout
可以在失敗時從新發送 Tuple, 不可靠的 Spout
一旦把 Tuple 發送出去就置之不理了。github
Bolts
是流數據的處理單元,它能夠從一個或者多個 Streams
中接收數據,處理完成後再發射到新的 Streams
中。Bolts
能夠執行過濾 (filtering),聚合 (aggregations),鏈接 (joins) 等操做,並能與文件系統或數據庫進行交互。數據庫
spouts
和 bolts
在集羣上執行任務時,是由多個 Task 並行執行 (如上圖,每個圓圈表明一個 Task)。當一個 Tuple 須要從 Bolt A 發送給 Bolt B 執行的時候,程序如何知道應該發送給 Bolt B 的哪個 Task 執行呢?apache
這是由 Stream groupings 分組策略來決定的,Storm 中一共有以下 8 個內置的 Stream Grouping。固然你也能夠經過實現 CustomStreamGrouping
接口來實現自定義 Stream 分組策略。網絡
Shuffle grouping架構
Tuples 隨機的分發到每一個 Bolt 的每一個 Task 上,每一個 Bolt 獲取到等量的 Tuples。負載均衡
Fields grouping分佈式
Streams 經過 grouping 指定的字段 (field) 來分組。假設經過 user-id
字段進行分區,那麼具備相同 user-id
的 Tuples 就會發送到同一個 Task。大數據
Partial Key grouping
Streams 經過 grouping 中指定的字段 (field) 來分組,與 Fields Grouping
類似。可是對於兩個下游的 Bolt 來講是負載均衡的,能夠在輸入數據不平均的狀況下提供更好的優化。
All grouping
Streams 會被全部的 Bolt 的 Tasks 進行復制。因爲存在數據重複處理,因此須要謹慎使用。
Global grouping
整個 Streams 會進入 Bolt 的其中一個 Task,一般會進入 id 最小的 Task。
None grouping
當前 None grouping 和 Shuffle grouping 等價,都是進行隨機分發。
Direct grouping
Direct grouping 只能被用於 direct streams 。使用這種方式須要由 Tuple 的生產者直接指定由哪一個 Task 進行處理。
Local or shuffle grouping
若是目標 Bolt 有 Tasks 和當前 Bolt 的 Tasks 處在同一個 Worker 進程中,那麼則優先將 Tuple Shuffled 處處於同一個進程的目標 Bolt 的 Tasks 上,這樣能夠最大限度地減小網絡傳輸。不然,就和普通的 Shuffle Grouping
行爲一致。
也叫作 Master Node,是 Storm 集羣工做的全局指揮官。主要功能以下:
也叫作 Worker Node , 是 Storm 集羣的資源管理者,按需啓動 Worker 進程。主要功能以下:
Nimbus 和 Supervisor 進程都被設計爲快速失敗(遇到任何意外狀況時進程自毀)和無狀態(全部狀態保存在 Zookeeper 或磁盤上)。 這樣設計的好處就是若是它們的進程被意外銷燬,那麼在從新啓動後,就只須要從 Zookeeper 上獲取以前的狀態數據便可,並不會形成任何數據丟失。
Storm 集羣的任務構造者 ,構造 Spoult 或 Bolt 的 Task 實例,啓動 Executor 線程。主要功能以下:
Storm 集羣的任務執行者 ,循環執行 Task 代碼。主要功能以下:
1 個 Worker 進程執行的是 1 個 Topology 的子集,不會出現 1 個 Worker 爲多個 Topology 服務的狀況,所以 1 個運行中的 Topology 就是由集羣中多臺物理機上的多個 Worker 進程組成的。1 個 Worker 進程會啓動 1 個或多個 Executor 線程來執行 1 個 Topology 的 Component(組件,即 Spout 或 Bolt)。
Executor 是 1 個被 Worker 進程啓動的單獨線程。每一個 Executor 會運行 1 個 Component 中的一個或者多個 Task。
Task 是組成 Component 的代碼單元。Topology 啓動後,1 個 Component 的 Task 數目是固定不變的,但該 Component 使用的 Executor 線程數能夠動態調整(例如:1 個 Executor 線程能夠執行該 Component 的 1 個或多個 Task 實例)。這意味着,對於 1 個 Component 來講,#threads<=#tasks
(線程數小於等於 Task 數目)這樣的狀況是存在的。默認狀況下 Task 的數目等於 Executor 線程數,即 1 個 Executor 線程只運行 1 個 Task。
總結以下:
更多大數據系列文章能夠參見 GitHub 開源項目: 大數據入門指南