storm中有兩個重要的組件——spout,bolt
spout負責接受數(shù)據(jù)源數(shù)據(jù)進行分發(fā)
bolt負責接受數(shù)據(jù)進行計算,傳向下一個bolt或者是進行存儲操作
spout和bolt通過topology串聯(lián),擁有許多的串聯(lián)方式,包括:
隨機數(shù)據(jù)流:數(shù)據(jù)從上游的spout或bolt隨機打到下游的bolt中。保證每個bolt收到相似的元組(數(shù)據(jù)流單位)。
域數(shù)據(jù)流:允許你基于元組的一個或多個域控制如何把元組發(fā)送給bolts。它保證擁有相同域組合的值集發(fā)送給同一個bolt。如下的實例


域聲明圖顯示在bolt或spout中聲明輸出的域,而域數(shù)據(jù)流拓撲顯示了如何依據(jù)指定域來劃分向下游透出的數(shù)據(jù)元組。
全部數(shù)據(jù)流:為每個接收數(shù)據(jù)的實例復制一份元組副本。這種分組方式用于向bolts發(fā)送信號。比如:你想向所有的bolt都發(fā)送定時執(zhí)行的任務指令。
自定義數(shù)據(jù)流:你可以通過實現(xiàn)backtype.storm.grouping.CustormStreamGrouping接口創(chuàng)建自定義數(shù)據(jù)流組,讓你自己決定哪些bolt接收哪些元組。

如圖所示就是一個自定義的數(shù)據(jù)流組,依據(jù)首字母劃分。
直接數(shù)據(jù)流:數(shù)據(jù)源可以用它決定哪個組件接收元組。
一個普通的spout如下圖所示:

該spout不斷的從文件中讀取數(shù)據(jù),然后分發(fā)到下游的bolt中。
但是這種spout并不保證可靠交付,要在spout中管理可靠性,你可以在分發(fā)時包含一個元組的消息ID(collector.emit(new Values(…),tupleId))。在一個元組被正確的處理時調(diào)用ack方法,而在失敗時調(diào)用fail方法。當一個元組被所有的靶bolt和錨bolt處理過,即可判定元組處理成功。
你可以在fail里面定義一些失敗的處理邏輯,比如失敗重新發(fā)送,保證消息一定能成功到達下一個bolt,或者失敗超過一定次數(shù)終止topology
一個典型的bolt如下所示:

元組的souceStreamId是上游component傳遞的,未指定的話就是"default",collector的emit方法有多種傳遞的方式,可以指定streamId和messageId,感興趣的可以去看下Stream的相關源碼。
這bolt同樣不能保證可靠性。可以在執(zhí)行完后顯示的調(diào)用collector.ack(tuple),來確保消息的可靠,BaseBasicBolt類實現(xiàn)了IBasicBolt的接口會在執(zhí)行完后自動調(diào)用ack。Storm可以沿著元組追蹤到始發(fā)spout。collector.ack(tuple)和collector.fail(tuple)會告知spout每條消息都發(fā)生了什么。當樹上的每條消息都已被處理了,Storm就認為來自spout的元組被全面的處理了。如果一個元組沒有在設置的超時時間內(nèi)完成對消息樹的處理,就認為這個元組處理失敗。默認超時時間為30秒。