kafka消息傳輸的事務定義

以前討論了consumer和producer是怎麼工做的,如今來討論一下數據傳輸方面。數據傳輸的事務定義一般有如下三種級別:linux

  1. 最多一次: 消息不會被重複發送,最多被傳輸一次,但也有可能一次不傳輸。網絡

  2. 最少一次: 消息不會被漏發送,最少被傳輸一次,但也有可能被重複傳輸.異步

  3. 精確的一次(Exactly once): 不會漏傳輸也不會重複傳輸,每一個消息都傳輸被一次並且僅僅被傳輸一次,這是你們所指望的。ide

大多數消息系統聲稱能夠作到「精確的一次」,可是仔細閱讀它們的的文檔能夠看到裏面存在誤導,好比沒有說明當consumer或producer失敗時怎麼樣,或者當有多個consumer並行時怎麼樣,或寫入硬盤的數據丟失時又會怎麼樣。kafka的作法要更先進一些。當發佈消息時,Kafka有一個「committed」的概念,一旦消息被提交了,只要消息被寫入的分區的所在的副本broker是活動的,數據就不會丟失。關於副本的活動的概念,下節文檔會討論。如今假設broker是不會down的。
若是producer發佈消息時發生了網絡錯誤,但又不肯定實在提交以前發生的仍是提交以後發生的,這種狀況雖然不常見,可是必須考慮進去,如今Kafka版本尚未解決這個問題,未來的版本正在努力嘗試解決。
並非全部的狀況都須要「精確的一次」這樣高的級別,Kafka容許producer靈活的指定級別。好比producer能夠指定必須等待消息被提交的通知,或者徹底的異步發送消息而不等待任何通知,或者僅僅等待leader聲明它拿到了消息(followers沒有必要)。oop

如今從consumer的方面考慮這個問題,全部的副本都有相同的日誌文件和相同的offset,consumer維護本身消費的消息的offset,若是consumer不會崩潰固然能夠在內存中保存這個值,固然誰也不能保證這點。若是consumer崩潰了,會有另一個consumer接着消費消息,它須要從一個合適的offset繼續處理。這種狀況下能夠有如下選擇:spa

 

  • consumer能夠先讀取消息,而後將offset寫入日誌文件中,而後再處理消息。這存在一種可能就是在存儲offset後還沒處理消息就crash了,新的consumer繼續從這個offset處理,那麼就會有些消息永遠不會被處理,這就是上面說的「最多一次」。日誌

  • consumer能夠先讀取消息,處理消息,最後記錄offset,固然若是在記錄offset以前就crash了,新的consumer會重複的消費一些消息,這就是上面說的「最少一次」。orm

  • 「精確一次」能夠經過將提交分爲兩個階段來解決:保存了offset後提交一次,消息處理成功以後再提交一次。可是還有個更簡單的作法:將消息的offset和消息被處理後的結果保存在一塊兒。好比用Hadoop ETL處理消息時,將處理後的結果和offset同時保存在HDFS中,這樣就能保證消息和offser同時被處理了。事務

相關文章
相關標籤/搜索