Kafka訊息delivery可靠性保證(Message Delivery Semantics)
阿新 • • 發佈:2018-12-23
原文見:http://kafka.apache.org/documentation.html#semantics
kafka在生產者和消費者之間的傳輸是如何保證的,我們可以知道有這麼幾種可能提供的delivery guarantee:
- At most once 訊息可能會丟,但絕不會重複傳輸
- At least one 訊息絕不會丟,但可能會重複傳輸
- Exactly once 每條訊息肯定會被傳輸一次且僅傳輸一次,很多時候這是使用者所想要的。
值得注意的是,當Producer向broker傳送訊息時,一旦這條訊息被commit,因數replication的存在,它就不會丟。但是如果Producer傳送資料給broker後,遇到網路問題而造成通訊中斷,那Producer就無法判斷該條訊息是否已經commit。雖然Kafka無法確定網路故障期間發生了什麼,但是Producer可以生成一種類似於主鍵的東西,發生故障時冪等性的重試多次,這樣就做到了Exactly once。目前這一Feature還並未實現,有希望在Kafka未來的版本中實現。(所以目前預設情況下一條訊息從Producer到broker是確保了At least once,可通過設定Producer非同步傳送實現At most once)。
- 讀完訊息先commit消費狀態(儲存offset)再處理訊息。這種模式下,如果Consumer在commit後還沒來得及處理訊息就crash了,下次重新開始工作後就無法讀到剛剛已提交而未處理的訊息,這對應at-most-once。
- 讀完訊息先處理再commit消費狀態(儲存offset)。這種模式下,如果在處理完訊息之後commit之前Consumer crash了,下次重新開始工作時還會處理剛剛未commit的訊息,實際上該訊息已經被處理過了。這對應at-least-once。
- 如果一定要做到exactly once,就需要協調offset和實際操作的輸出。經典的做法是引入兩階段提交,如果能讓offset和操作輸入存到同一個地方,會更簡潔和通用。這種方式可能更好,因為許多輸出系統可能不支援兩階段提交。比如,Consumer拿到資料後可能把資料放到HDFS,如果把最新的offset和資料本身一起寫到HDFS,那就可以保證資料的輸出和offset的更新要麼都完成,要麼都不完成,間接實現Exactly once。目前就high level api而言,offset是存於Zookeeper中的,無法存於HDFS,而low level API的offset是由自己去維護的,可以將之存於HDFS中.
Kafka預設保證At least once,並且允許通過設定Producer非同步提交來實現At most once。而Exactly once要求與外部儲存系統協作,幸運的是Kafka提供的offset可以非常直接非常容易得使用這種方式。
參考:
http://kafka.apache.org/documentation.html#semantics