Kafka如何保證訊息不丟之無訊息丟失配置

凱凱王的技術生涯發表於2020-11-26

已提交與有限度

Kafka對已提交的訊息有限度的持久化保證。

  • 已提交訊息:Kafka的若干個Broker成功接收到訊息並寫入日誌檔案後,告訴生產者已成功提交。已提交的定義如下
    • 一個Broker成功儲存訊息為已提交
    • 所有Broker都成功儲存訊息為已提交
  • 有限度的持久化保證:有限度的意思是假如有N個Broker,要想保證持久化,就至少有一個存活。

生產者丟失資料

非同步傳送訊息

當非同步傳送訊息的時候,會立即返回,但是不能認為訊息傳送成功,這個操作代表的意思是傳送後不管。出現丟訊息的原因如下:

  • 網路抖動,訊息沒有傳送到Broker端
  • 訊息不合格,被Broker拒絕接受

解決方式

Producer 永遠要使用帶有回撥通知的傳送 API,也就是說不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。

當出現訊息失敗的情況,針對性的做相應處理即可

消費者丟失資料

Consumer 端丟失資料主要體現在 Consumer 端要消費的訊息不見了
在這裡插入圖片描述
ConsumerA 當前位移值是9,ConsumerB當前位移值是11

更新offset時機

通過消費訊息、然後再更新位移,這樣能最大限度的保證訊息不丟失,但是有可能帶來訊息重複消費的問題

設定手動提交

Consumer不要開啟自動提交位移,通過應用程式手動提交位移

最佳實踐

  • 使用帶有回撥通知的send方法producer.send(msg, callback)。
  • 設定 acks = all,代表所有的副本Broker都要收到訊息才算是已提交,最高階別的已提交定義
  • 設定retries為一個較大的值。自動重試訊息,避免是吧
  • Broker引數unclean.leader.election.enable = false。控制哪些Broker有資格競選分割槽的Leader。
  • Broker引數 replication.factor>=3,將訊息儲存多份,通過冗餘來方式丟失
  • Broker引數 min.insync.replicas > 1,控制訊息至少要被寫入多個副本才算是已提交。
  • replication.factor > min.insync.replicas,兩者相等,那麼只要有一個副本掛機,整個分割槽就無法正常工作了,推薦設定為replication.factor = min.insync.replicas + 1。
  • 確保訊息消費完再提交。Consumer端有個引數enable.auto.commit,最好把它設定成 false,並採用手動提交位移的方式。

相關文章