https://github.com/alibaba/jstorm/wiki/Ack-%E6%9C%BA%E5%88%B6
Storm也支持ACK機制
(1)應用場景
通過Ack機制,spout發送出去的每一條消息,都可以確定是被成功處理或失敗處理, 從而可以讓開發者采取動作。比如在Meta中,成功被處理,即可更新偏移量,當失敗時,重復發送數據。
因此,通過Ack機制,很容易做到保證所有數據均被處理,一條都不漏。
另外需要注意的,當spout觸發fail動作時,不會自動重發失敗的tuple,需要spout自己重新獲取數據,手動重新再發送一次
ack機制即, spout發送的每一條消息,
==》在規定的時間內,spout收到Acker的ack響應,即認為該tuple 被后續bolt成功處理
==》在規定的時間內,沒有收到Acker的ack響應tuple,就觸發fail動作,即認為該tuple處理失敗,
==》或者收到Acker發送的fail響應tuple,也認為失敗,觸發fail動作
另外Ack機制還常用于限流作用: 為了避免spout發送數據太快,而bolt處理太慢,常常設置pending數,當spout有等于或超過pending數的tuple沒有收到ack或fail響應時,跳過執行nextTuple, 從而限制spout發送數據。
通過conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, pending);
設置spout pend數。
(2)如何使用Ack機制
==》spout 在發送數據的時候帶上msgid
==》設置acker數至少大于0;Config.setNumAckers(conf, ackerParal);
==》在bolt中完成處理tuple時,執行OutputCollector.ack(tuple), 當失敗處理時,執行OutputCollector.fail(tuple); ** 推薦使用IBasicBolt, 因為IBasicBolt 自動封裝了OutputCollector.ack(tuple), 處理失敗時,請拋出FailedException,則自動執行OutputCollector.fail(tuple)**
(3)如何關閉Ack機制
有2種途徑
==》spout發送數據是不帶上msgid
==》設置acker數等于0
(4)原理
acker對于每個spout-tuple保存一個ack-val的校驗值,它的初始值是0, 然后每發射一個tuple/ack一個tuple,那么tuple的id都要跟這個校驗值異或一下, 并且把得到的值更新為ack-val的新值。那么假設每個發射出去的tuple都被ack了, 那么最后ack-val一定是0(因為一個數字跟自己異或得到的值是0)。