理解storm的ACKER機制原理

破棉襖發表於2014-09-01

一、簡介:
   
  storm中有
個很重要的特性:    

           保證發出的每個tuple都會被完整處理。一個tuple被完全處理的意思是: 這個tuple以及由這個tuple所產生的所有的子tuple都被成功處理。
          
如果任一個訊息在timeout所指定的時間內沒有完成處理,那這個tuple就失敗了



二、原理
    

        acker並不會為每個tuple都分配記憶體空間來完成跟蹤,而是利用了一個非常巧妙的演算法,這個演算法只需使用恆定的20位元組就可以完成整個tuple樹的跟蹤。
     
   具體原理:

         acker對於每個spout-tuple儲存一個ack-val的校驗值,它的初始值是0, 然後每發射一個tuple/ack一個tuple,那麼tuple的id都要跟這個校驗值異或一下,
        並且把得到的值更新為ack-val的新值。那麼假設每個發射出去的tuple都被ack了, 那麼最後ack-val一定是0(因為一個數字跟自己異或得到的值是0)。


  通俗理解:
         

       1.在spout產生一條tuple時,會向acker傳送一條資訊,讓ack來進行跟蹤,訊息內容:
             
{spout-tuple-id {:spout-task task-id :val ack-val}}
              spout-tuple-id:這條tuple的id,每條tuple都會產生一個隨機的MessageId
              task-id:產生這條tuple的id,spout可能有多個task,每個task都會被分配一個唯一的taskId
              ack-val:預設值為0,用來跟蹤tuple
      
                  
     2.acker會在自己的map(型別為TimeCacheMap)裡儲存這條記錄。 這就是acker對spout-tuple進行跟蹤的核心資料結構, 對於每個spout-tuple所產生的tuple樹的跟蹤
       都只需要儲存上面這條記錄。acker後面會檢查:val什麼時候變成0,變成0, 說明這個spout-tuple產生的tuple都處理完成了。

     
    3.spout在傳送完訊息給acker後會將該tupleMessageId傳送到boltTask。boltTask在建立子tuple時並不會向acker傳送訊息讓其跟蹤,而是很巧妙的省略了這一步:
      bolt在發射一個新的bolt的時候會把這個新tuple跟它的父tuple的關係儲存起來(strom稱之為anchoring)。然後在ack tuple的時候,storm會把要ack的tuple的id, 以及
     這個tuple新建立的所有的tuple的id的異或值傳送給acker。訊息格式是:(spout-tuple-id,tmp-ack-val)執行完這一步後,ack-val的值就變成了所有子tuple的id的異或值
      ps:storm使用一致性雜湊來把一個spout-tuple-id對應到acker, 因為每一個tuple知道它所有的祖宗的tuple-id, 所以它自然可以算出要通知哪個acker來ack

    4.當所有子tuple都被ack之後,val會被異或成0,OK 整個tuple樹執行跟蹤完成。


場景分析:

     1. 由於對應的task掛掉了,一個tuple沒有被ack: storm的超時機制在超時之後會把這個tuple標記為失敗,從而可以重新處理。

     2. Acker掛掉了: 這種情況下由這個acker所跟蹤的所有spout tuple都會超時,也就會被重新處理。

     3. Spout掛掉了: 在這種情況下給spout傳送訊息的訊息源負責重新傳送這些訊息。比如Kestrel和RabbitMQ在一個客戶端斷開之後會把所有”處理中“的訊息放回佇列。

    由此可見storm的高度容錯性。
   

    
注意:
       當spout收到ack或fail message如何處理:
       首先是從pending list裡面刪掉這條tuple,因為無論ack或fail,只要得到結果,這條tuple就沒有繼續被cache的必要了
       然後做的事是呼叫spout.ack或spout.fail
       所以系統預設是不會做任何事的,甚至是fail後的重發,你也需要在fail裡面自己實現 (可以自己cache,然後根據fail的msgId去查詢msg然後重發,據說Jstorm提供了msg)
     此策略會有重複處理的問題

     

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29754888/viewspace-1261363/,如需轉載,請註明出處,否則將追究法律責任。

相關文章