19. Storm Topology開發

一. wordCount Topology開發:

1.spout數據收集器(SentenceSpout類):

有兩種方法來開發spout類,第一種是實現backtype.storm.topology.IRichSpout接口,第二種是繼承backtype.storm.topology.base.BaseRichSpout類。
其中,IRichSpout接口提供了更多的一些需要實現的方法,BaseRichSpout類只提供了3個需要實現的方法。

    @Override
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
        // TODO Auto-generated method stub
        this.collector = collector;
    }
    @Override
    public void close() {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void activate() {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void deactivate() {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void nextTuple() {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void ack(Object msgId) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void fail(Object msgId) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public Map<String, Object> getComponentConfiguration() {
        // TODO Auto-generated method stub
        return null;
    }

上邊的這些方法中,有幾個比較重要,需要實現。
1.nextTuple():
在該方法中,編寫從數據源獲取數據的邏輯。該方法程序循環調用,collector.emit()向后邊的bolt發射數據。
2.declareOutputFields():
該方法聲明向后邊發射的記錄的字段名稱。
3.tuple
collector.emit()方法發射的內容是Tuple,類型為List<Object> tuple。 tuple元組是一系列key,value對的集合。例如:(a:a_value,b:b_value,c:c_value,...,n:n_value)。其中,collector.emit(new Values())聲明的是tuple的value值,而declarer.declare(new Fields())聲明的是tuple的key值,兩者是一一對應的(假如new Values(val1,val2),那么,declarer.declare(new Fields(key1,key2))也需要聲明2個值,并且key1對一個val1,key2對應val2)。
4.open():
該方法是初始化方法,將會第一個被調用,一般,我們可以在該方法內實例化定義的類。

2.bolt組件(SplitBolt、CountBolt類):

開發bolt組件,需要實現backtype.storm.topology.IRichBolt接口,或者繼承類backtype.storm.topology.base.BaseRichBolt。
下面幾個方法比較重要:
1.prepare()
初始化方法,將會第一個被調用,一般,我們可以在該方法內實例化定義的類。
2.execute()
循環調用,被動執行,前面數據來源向該bolt發射tuple的時候,就會調用execute方法。
3.declareOutputFields
與spout相同。

3.Topology驅動類(WordsToplogy類):

向集群提交Topology,需要使用類backtype.storm.topology.TopologyBuilder。TopologyBuilder類可以配置spout、bolt組件的記錄發射關系(前后依賴關系,例如:spout --> bolt1 -->bolt2等)。

TopologyBuilder builder = new TopologyBuilder();        
builder.setSpout("Spout", new SentenceSpout());
builder.setBolt("SplitBolt", new SplitBolt()).shuffleGrouping("Spout");
builder.setBolt("CountBolt", new CountBolt())
 .fieldsGrouping("SplitBolt", new Fields("Word"));

所謂的grouping策略就是在Spout與Bolt、Bolt與Bolt之間傳遞Tuple的方式。Grouping分組策略主要有以下幾種:
1.shuffleGrouping:隨機分組。將流分組定義為混排。這種混排分組意味著來自Spout的輸入將混排,或隨機分發給此Bolt中的任務。shuffle grouping對各個task的tuple分配的比較均勻。
2.fieldsGrouping:按照字段分組。Storm能保證所有相同Field值的數據到達的是相同的Blot,但是不保證一個Blot只處理一個值域。這對于分組統計的應用來說是比較重要的,如果分組不正確的話會造成統計出錯。
3.globalgrouping:全局分組,前面組件的數據,全部只會往該組件的其中一個上傳送。
4.allGrouping:廣播發送,即每一個Tuple,每一個Bolt都會收到。

4.Storm集群參數配置:

對于storm集群的參數,可以通過Config對象來配置。

Config conf = new Config();
conf.setMaxSpoutPending(10);

也可以通過conf.put(key, value)來配置xml文件中的參數。

5.單機運行或者提交storm集群:

單機提交topology(主要用于提交集群前的測試,非常重要)。使用LocalCluster類來提交單機測試topology:

LocalCluster local = new LocalCluster();
local.submitTopology("LocalTest", conf, builder.createTopology());

集群提交topology:

StormSubmitter.submitTopology("WordCount", conf, builder.createTopology());

6.代碼示例:

下面的代碼實現了一個詞頻統計的storm實例,功能非常簡單,隨機發送sentence并拆分統計單詞。
https://github.com/neil-ma/storm-pmpa/tree/master/storm-pirate/src/main/java/com/pmpa/storm/words

二. Topology并發控制:

1.并發控制組件:

Storm的并發度最終表示的Task的并發度。Storm執行架構有三個層次 Worker -> Executor -> Task。配置以上3個組件的數量來控制并發度。
Worker進程:針對具體的Topology,worker上只運行與之相關的Topology,一個worker進程上可以啟動多個executor線程。
Executor線程:針對具體的task(spout、bolt),一個Executor線程上可以跑多個task,默認一個Executor運行一個task。
Task:指定多個task來運行spout或者bolt組件。

2.參數配置:

1.Worker進程數量:
通過Config設置 : conf.setNumWorkers(4); // 設置worker個數為4
Supervisor進程負責啟動worker,假如有3個supervior,這3個supervisor會平均配置4個Worker,例如: 2 1 1 。
2.Executor個數:
在構造Topology時,在setSpout()或者setBolt()方法中設定executor的數量。例如下例子:

builder.setBolt("SplitBolt", new SplitBolt(),3).shuffleGrouping("Spout")

代碼表示,需要啟動3個executor來運行SplitBolt。需要注意的是,這里表示一共有3個executor,而不是每個worker上運行3個executor。假如說,config的配置一共有2個worker,那么分配的結果就是一個worker上執行2個executor,另一個worker上執行1個executor。后邊的task配置也是一樣的道理。
3.task個數
task的數量由setNumTasks()方法確定,例如下邊的定義:

builder.setBolt("SplitBolt", new SplitBolt(),3).shuffleGrouping("Spout")
  .setNumTasks(6);

上邊代碼表示3個executor共執行6個task,storm會平均分配一個executor執行2個task(系統自動做到盡量均勻)。如果不指定setNumTasks()方法,默認1個Executor運行一個Task,上邊代碼如果不指定setNumTasks()方法會有3個Task執行。

三. Storm消息可靠性保障機制:

對于某些實時大數據應用,例如銀行的實時數據、交管部門的實時數據等,需要保證數據的可靠性,在實施這類應用時,就需要開啟storm的消息可靠性保障機制。消息可靠性保障機制實際上就是Storm需要對spout發送的每一條消息是否被后續的bolt成功處理完成有一條反饋。

1.原理和機制:

1.ack機制:
為了保證storm的每條記錄都能正確處理,Storm會對Spout發送的每一個tuple進行跟蹤。這里面包括ack/fail的處理,一個tuple處理成功是指這個Tuple以及這個Tuple產生的所有Tuple都被成功處理, 會調用spout的ack方法;失敗是指這個Tuple或這個Tuple產生的所有Tuple中的某一個tuple處理失敗, 則會調用spout的fail方法;在處理tuple的每一個bolt都會通過OutputCollector來告知storm, 當前bolt處理是否成功。
2.ack原理:
Storm中有個特殊的task名叫acker,他們負責跟蹤spout發出的每一個Tuple的Tuple樹。當acker(框架自啟動的task)發現一個Tuple樹已經處理完成了,它會發送一個消息給產生這個Tuple的那個task。

2.實現:

1.spout處理:
(1)spout往后發射tuple時,需要指定一個msgId。

2.bolt處理:
(1)bolt處理接收到tuple,如果還需要繼續往后邊的bolt發射,需要追溯前邊的tuple(這么做的目的是構建Tuple樹)

collector.emit(input,new Values(word));

(2)處理完bolt,一定要調用collector的ack方法,

四. Trident介紹和實現:

1. 問題:

前邊介紹的基礎的storm都是逐條處理數據的(一個tuple、一個tuple處理)。在生產環境中,一般都是Kafka + Storm + HBase/Redis 架構處理實時數據。如果只是逐條處理的話,對下游數據庫(HBase、Redis)的壓力就會非常大。
Trident是Storm提供的解決方案,一個批次一個批次處理實時數據,其中一個批次封裝了多條tuple。Trident能夠提高數據處理效率和性能,同時也減小了對后端數據庫的壓力。因為Trident是以批次為單位來處理數據的,所以這里就涉及到事務的問題。Trident中已經封裝了事務管理、狀態管理的功能(框架幫我們自動實現),而且還封裝了一系列的常用操作,鏈式調用。真正實現流式處理數據。
Storm從0.7版本開始引入事務管理,之前版本中提供的Transactional Topology API已經廢棄不用了。

2. Storm事務管理:

Storm事務管理分為3個層次:
(1)No Transactional:
不進行事務管理。一個批次中的tuple可能有的成功,有的失敗,不限制一致性。tuple處理成功次數可能不止一次,同一個tuple可能在多個批次中處理,并且都成功,也可能一次都不成功。
(2)Transactional :
保證tuple只會在一個批次中出現,即使失敗重試,tuple的批次號還是不變的,同一個tuple保證最多成功一次。
(3)Opaque Transactional:
不透明事務,和第2種類似。相比于第2種,提供了容錯的機制。某些tuple在某個批次中處理失敗后,可以在另外一個批次里處理成功(失敗后,將該tuple轉到另外一個批次中處理),但不會成功多次。

3. Storm事務原理:

(1)將多條tuple封裝成一個批次,并且給該批次指定一個唯一的批次號(batchId)。
(2)后邊組件處理數據按照批次先后順序處理(前邊的批次更新后,才能處理后邊的批次),結果的更新,一定是前面的批次更新成功后才能進行后面的批次結果更新。

4. WordCountTridentTopology實現:

TridentTopology需要開發自己的spout(以前是逐條發送tuple,現在的需要將多條tuple封裝成一個batch發送),自己的function(在trident中不叫bolt,而是function,實現的功能與bolt一樣),下面實現了一個最簡單的實例:
https://github.com/neil-ma/storm-pmpa/tree/master/storm-pirate/src/main/java/com/pmpa/storm/wordstrident

五. Trident編程:

1. 編寫Trident Spout:

編寫Trident Spout需要自行實現將tuple打包成batch的邏輯。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容