Apache Storm 官方文檔 —— Ack 框架的實現
Storm 的 acker 使用哈希校驗和來跟蹤每個 tuple 樹的完成情況:每個 tuple 在被發送出的時候,它的值會與校驗和進行異或運算,然後在 tuple 被 ack 的時候這個值又會再次與校驗和進行異或運算。這樣,一旦所有的 tuple 都被成功 ack,校驗和就會變為 0(隨機生成的校驗和為 0 的概率極小,可以忽略不計)。
你可以在 wiki 中了解更多關於可靠性機製的信息。
acker execute()
Acker 實際上也是一個 bolt,它的 execute 方法 是定義在 mk-acker-bolt
中的。在一個新的 tuple 樹生成的時候,spout 為每個 tuple 發送一個用於異或的固有 id,acker 會將這些 id 記錄在它的掛起隊列中。每次 executor ack 一個 tuple 的時候,acker 會接收到一個部分校驗和,這個校驗和是 tuple 自身的 id(將其從掛起隊列中清除)和 executor 發送的每個下遊 tuple 的 id(放入掛起隊列中)的異或值。
這個過程是這樣的:
在接收到 tick tuple 信號的時候,將 tuple 樹的校驗值向超時方向移動並且返回。同時,在 tuple 樹中更新或者創建一個記錄。
- 初始化階段:使用指定的校驗和值進行初始化,並且記錄 spout 的 id;
- ack 階段:將部分校驗和與當前的校驗和進行異或運算;
- fail 階段:僅僅將 tuple 標記為 failed 狀態。
接下來,將記錄存入 RotatingMap(重新設置超時計數值)並且繼續以下過程:
- 如果總校驗和為 0, 表明 tuple 樹已經完成:將記錄從掛起隊列中移除,並通知 spout 處理成功;
- 如果 tuple 樹失敗了,也會有一種完成狀態:將記錄從掛起隊列中移除,並通知 spout 處理失敗。
最後,發送一個我們自己的 ack 信號。
掛起 tuples 與 RotatingMap
Acker 將掛起樹存放在一個 RotatingMap
中。RotatingMap
是一個在 Storm 中多處使用的簡單工具,它主要用於高效地處理過程的超時。
RotatingMap 與 HashMap 類似,支持 O(1) 時間的 get 操作。
在 RotatingMap 內部有多個 HashMap(稱為槽,buckets),每個 HashMap 都保存有一群會在同一時間超時的記錄。我們稱存在時間最長的 bucket 為死亡牢房(death row),而訪問最多的 bucket 稱為苗圃(nursery)。一個新的值在被.put()
到 RotatingMap 中,它都會被重定位到 nursery 中,並且從其他的它之前可能在的 bucket 中移除(這是一種高效的重新設置延時時間的方法)。
在 RotatingMap 的所有者調用 .rotate()
方法的時候,RotatingMap 會將每個 bucket 向著超時的方向移動一步(一般 Storm 對象會在收到一個係統 tick 流 tuple 的時候調用 rotate 方法)。如果此時在前麵所說的 death row bucket 中有 key-value 鍵值對,RotatingMap 會為每個 key-value 鍵值對觸發一個回調函數(在構造器中定義的),讓他們的所有者選擇一個合適的操作(例如,將 tuple 標記為處理
失敗)。
最後更新:2017-05-22 13:31:51