1. 程式人生 > >Apache Storm 官方文件 —— Ack 框架的實現

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 標記為處理失敗)。