轉載自http://www.cnblogs.com/Jack47/p/understanding_the_parallelism_of_a_storm_topology.htmlhtml
本篇文章介紹了Storm拓撲的併發模型。介紹了Worker進程,Executor(線程)和Task(任務)之間的關係,如何按照須要配置他們。本文基於Storm 0.8.1版本,最新發布版本已經到了0.9.5了。java
在Storm集羣上運行的拓撲主要包含如下的三個實體:web
下圖簡單闡釋了他們之間的關係:
shell
圖1:Storm中worker進程,executor(線程)和任務的關係apache
一個正在運行的拓撲由不少worker進程組成,這些worker進程在Storm集羣的多臺機器上運行。一個worker進程屬於一個特定的拓撲而且執行這個拓撲的一個或多個component(spout或者bolt)的一個或多個executor。一個worker進程就是一個Java虛擬機(JVM),它執行一個拓撲的一個子集。api
一個executor是由一個worker進程產生的一個線程,它運行在worker的Java虛擬機裏。一個executor爲同一個component(spout或bolt)運行一個或多個任務。一個executor總會有一個線程來運行executor全部的task,這說明task在executor內部是串行執行的。緩存
真正的數據處理邏輯是在task裏執行的,在父executor線程執行過程當中會運行task。在代碼中實現的每一個spout或bolt是在全集羣中以不少task的形式運行的。一個component的task數量在這個拓撲的生命週期中是固定不變的,可是一個component的executor(線程)數量會隨着時間推移發生變化。這說明如下條件一直成立:threads數量 <= task數量
。默認狀況下task數量被設置成跟executor的數量是同樣的,即Storm會在每一個線程上執行一個任務(這一般是你想要的)。安全
同時請注意:bash
storm rebalance
命令)。能夠看「理解Storm內部的消息緩存」來從另一個視角來看一個worker進程生命週期中運行的各類各樣的線程和跟這些線程關聯的executor和task。併發
注意Storm術語中「併發度(parallelism)「特定地用來描述所謂的"parallelism hint",它表明了一個component初始的executor(線程)數量。但在這篇文章中我使用更普遍意義的「併發度「來描述如何配置一個Storm拓撲中executor數量,worker進程數量以及task數量。當使用Storm中狹義的「併發度」時,我會特殊說明。
下表是各類配置項的概述以及如何在代碼中設置。有不止一種方法來設置這些選項,可是下表只列出了其中一些方法。Storm目前配置項的優先級是:外部component特定的配置>內部component特定的配置項>拓撲特定的配置項>storm.yaml>defaults.yaml。更多詳情能夠參閱Storm文檔。
用途 | 描述 | 配置項 | 如何經過代碼設置(例子) |
---|---|---|---|
worker進程數量 | 拓撲在集羣機器上運行時須要的worker進程數據量 | Config#TOPOLOGY_WORKERS | Config#setNumWorkers |
每一個組件須要建立的executor數量 | executor線程的數量 | 沒有單獨配置項 | TopologyBuilder#setSpout() 和 TopologyBuidler#setBolt() Storm 0.8以後使用 parallelism_hint參數來指定executor的初始數量 |
task數量 | 每一個組件須要建立的task數量 | Config#TOPOLOGY_TASKS | ComponentConfigurationDeclarer#setNumTasks() |
下面是一段如何實際設置這些配置的示例性代碼:
topologyBuilder.setBolt("green-bolt", new GreenBolt(), 2) .setNumTasks(4) .shuffleGrouping("blue-spout");
在上述代碼中咱們配置Storm以兩個executor和4個task的初始數量去運行greenBolt
。Storm會在每一個executor(線程)上運行兩個任務。若是你沒有顯示配置任務的數量,Storm會默認每一個executor運行一個任務。
在Storm 0.8.2中引入了隔離調度器,讓多個拓撲很容易且安全地共享一個集羣,例如,它解決了多租戶的問題--避免多個拓撲之間的資源競爭--經過提供拓撲間的徹底隔離
當使用隔離調度器的時候Nathan[Storm做者]建議你把worker數量設置成機器數量的倍數。把executor數量設置成worker數量的倍數。若是你會調用
setNumTasks()
(多數人不會),應該設置成executor數量的倍數。這樣作了以後,你的拓撲的負載就會均勻分佈。每臺機器和每一個Java虛擬機進程會有相同數量的線程和大體等量的負載。
下圖闡釋了在實際中一個簡單拓撲看起來長什麼樣子。拓撲包含三個組件(component):一個叫BlueSpout
的Spout
,兩個分別叫作GreenBolt
和YellowBolt
的Bolt
。組件相互鏈接而構成一個圖結構:BlueSpout
把輸出發送給GreenBolt
,一樣GreenBolt
把結果發送給YellowBolt
。
運行中拓撲的例子
還記得上面展現的配置GreenBolt
代碼嗎?BlueSpout
和YellowBolt
只設置了parallelism_hint
(executor數量)。下面是相關代碼:
Config conf = new Config(); conf.setNumWorkers(2); // use two worker processes topologyBuilder.setSpout("blue-spout", new BlueSpout(), 2); // parallelism hint topologyBuilder.setBolt("green-bolt", new GreenBolt(), 2).setNumTasks(4).shuffleGrouping("blue-spout"); topologyBuilder.setBolt("yellow-bolt", new YellowBolt(), 6).shuffleGrouping("green-bolt"); StormSubmitter.submitToplogy("mytopology", conf, topologyBuilder.createTopology());
Storm一個靈巧的功能是能夠增減worker進程或者executor的數量而不須要重啓集羣或者拓撲。這種作法叫作rebalancing
。
有兩種方法能夠用來作拓撲的rebalance
:
storm rebalance
命令行的例子:
# 從新配置「mytopology」拓撲使用5個worker進程[原來是2個] # "blue-spout"這個spout使用3個[原來有2個]executor # "yellow-bolt"使用10個[原來有6個]executor $ storm rebalance mytopology -n 5 -e blue-spout=3 -e yellow-bolt=10
通過上面的rebalance
命令,此時每一個Bolt各自有幾個executor,幾個task,每一個worker裏面分配了幾個executor?