storm(二) 事務機制
前言
為了保證tuple的強有序和exactly-once語義,storm提供了事務機制,為每個tuple提供一個id
設計方法1
為每個tuple設置一個事務id,在數據庫保存事務id和當前處理的id做比較。
1.兩個id不一樣,由於事務的強有序特點,判斷出該tuple沒有出現過,所以更新id
2.id一樣,重復出現,可以不用處理
問題:
這樣做會導致新能很低,每個tuple都必須處理完後才能處理下一個tuple(否則會影響和下一個tuple的順序),並且每個tuple還得至少訪問一次數據庫
設計方法2
單個性能慢,很自然的就想到了多個一起處理。多個tuple形成一個batch。這樣也可以保證強有序性
這樣性能就提高了很多,如果一個batch處理了1000個tuples,那麽性能就提高了1000倍。但是這還是沒有更好的把資源利用充分。每個batch都是一個個處理,第二個batch必須等第一個batch完全處理完之後才能開始處理。
設計方法3
(storm選擇的設計方法)
通過前兩中設計方法,我們意識到了一個關鍵的思想,並不是所有的處理過程都需要保證強有序。只要保證最終執行完的那瞬間是強有序就ok。抽象出每次處理都需要兩步。
1.計算一個batch的部分次數
2.在數據庫更新該batch的部分次數
storm實現把對一個batch的計算分成了兩塊
1.處理。在此環節可以並發處理多個batch
2.提交。在此環節只能處理1個batch。這樣就保證了強有序。
當這兩塊的其中某塊出現問題,該事務都會被重新執行。
其實這跟設計方法二有點相似,都用了batch的思想。並結合分治思想,把整體盡可能的拆成許多小碎片,對每一個碎片都用最優的方法處理。
設計細節
1.storm把事務相關的信息存儲在zookeeper中
2.storm會管理所有事務的處理或提交時機
3.關於容錯。storm利用ack機制,會在合適的時候自動回放失敗的事務。使用者不需要做任何acking
回放失敗的事務需要一個tuple源的隊列,比如kafka。
整體運行流程
Processer必須等前一個Committer完成提交後才能調用finishBatch。
關於事務失敗
由於事務框架屏蔽了Ack接口,提供了另一種方式,可以 throw FailedException.
關於配置
有兩個重要配置
1.事務依賴的zookeeper,默認和storm集群依賴的一樣,可以通過以下key修改
transactional.zookeeper.servers
2.同時處理batch的個數,默認是1,可以通過以下key修改
topology.max.spout.pending
參考資料
http://storm.apache.org/releases/1.1.1/Transactional-topologies.html
storm(二) 事務機制