kafka如何保證消息不丟失不被重複消費

kafka如何保證消息不丟失不被重複消費

在解決這個問題之前,我們首先梳理一下kafka消息的發送和消費機制。

消息的發送機制

kafka的消息發送機制分爲同步和異步機制。可以通過producer.type屬性進行配置。使用同步模式的時候,有三種狀態來保證消息的安全生產。可以通過配置request.required.acks屬性。三個屬性分別如下

  • 0—表示不進行消息接收是否成功的確認;
  • 1—表示當Leader接收成功時確認;
  • -1—表示Leader和Follower都接收成功時確認;

當acks = 0的時候,不和Kafka集羣進行消息接收確認,則當網絡異常、緩衝區滿了等情況時,消息可能丟失;當acks=1的時候,只保證leader寫入成功。當leader partition掛了的時候,數據就有可能發生丟失。另外還有一種情況,使用異步模式的時候,當緩衝區滿了,acks=0的時候,不需要進行消息接受是否成功的確認,所以會自動清空緩衝池裏的消息。

同步模式下只需要將確認機制設置爲-1,讓消息寫入leader和所有的副本,就可以保證消息安全生產。

異步模式下,則需要在配置文件中,將阻塞超時的時間設置爲不限制。這樣生產端會一直阻塞。可以保證數據不丟失。

我們需要設置block.on.buffer.full = true。 這樣producer將一直等待緩衝區直至其變爲可用。緩衝區滿了就阻塞

acks=all。所有的follwoer都響應了消息就認爲消息提交成功。

retries=MAX。無限重試。

max.in.flight.requests.per.connnection = 1限制客戶端在單個連接上能夠發送的未響應的請求的個數。設置爲1表示kafka broker在響應請求之前client不能再向broker發送請求了。通過此舉可以保證消息的順序性。

消息的接受機制

消息的接受端保證消息不丟失的情形就比較簡單了。kafka的consumer模式是自動提交位移的。我們只需要在代碼邏輯中保證位移提交前消息被處理就行。我們可以關閉自動提交位移,設置enable.auto.commit爲false。自己手動處理消息後提交位移。

消息的重複消費如何解決

重複消費的問題,一方面需要消息中間件來進行保證。另一方面需要自己的處理邏輯來保證消息的冪等性。極有可能代碼消費了消息,但服務器突然宕機,未來得及提交offset。所以我們可以在代碼保證消息消費的冪等性。至於方法可以通過redis的原子性來保證,也可以通過數據庫的唯一id來保證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章