storm中有兩個重要的組件——spout,bolt
spout負責接受數據源數據進行分發
bolt負責接受數據進行計算,傳向下一個bolt或者是進行存儲操作
spout和bolt通過topology串聯,擁有許多的串聯方式,包括:
隨機數據流:數據從上游的spout或bolt隨機打到下游的bolt中。保證每個bolt收到相似的元組(數據流單位)。
域數據流:允許你基于元組的一個或多個域控制如何把元組發送給bolts。它保證擁有相同域組合的值集發送給同一個bolt。如下的實例
域聲明圖顯示在bolt或spout中聲明輸出的域,而域數據流拓撲顯示了如何依據指定域來劃分向下游透出的數據元組。
全部數據流:為每個接收數據的實例復制一份元組副本。這種分組方式用于向bolts發送信號。比如:你想向所有的bolt都發送定時執行的任務指令。
自定義數據流:你可以通過實現backtype.storm.grouping.CustormStreamGrouping接口創建自定義數據流組,讓你自己決定哪些bolt接收哪些元組。
如圖所示就是一個自定義的數據流組,依據首字母劃分。
直接數據流:數據源可以用它決定哪個組件接收元組。
一個普通的spout如下圖所示:
該spout不斷的從文件中讀取數據,然后分發到下游的bolt中。
但是這種spout并不保證可靠交付,要在spout中管理可靠性,你可以在分發時包含一個元組的消息ID(collector.emit(new Values(…),tupleId))。在一個元組被正確的處理時調用ack方法,而在失敗時調用fail方法。當一個元組被所有的靶bolt和錨bolt處理過,即可判定元組處理成功。
你可以在fail里面定義一些失敗的處理邏輯,比如失敗重新發送,保證消息一定能成功到達下一個bolt,或者失敗超過一定次數終止topology
一個典型的bolt如下所示:
元組的souceStreamId是上游component傳遞的,未指定的話就是"default",collector的emit方法有多種傳遞的方式,可以指定streamId和messageId,感興趣的可以去看下Stream的相關源碼。
這bolt同樣不能保證可靠性??梢栽趫绦型旰箫@示的調用collector.ack(tuple),來確保消息的可靠,BaseBasicBolt類實現了IBasicBolt的接口會在執行完后自動調用ack。Storm可以沿著元組追蹤到始發spout。collector.ack(tuple)和collector.fail(tuple)會告知spout每條消息都發生了什么。當樹上的每條消息都已被處理了,Storm就認為來自spout的元組被全面的處理了。如果一個元組沒有在設置的超時時間內完成對消息樹的處理,就認為這個元組處理失敗。默認超時時間為30秒。