【Java面試】Kafka 怎麼避免重複消費

跟著Mic學架構發表於2022-06-24

Hi,大家好,我是Mic

一個工作5年的粉絲找到我。

他說: “Mic老師,你要是能回答出這個問題,我就佩服你”

我當場就懵了,現在打賭都這麼隨意了嗎?

我問他問題是什麼,他說“Kafka如何避免重複消費的問題!”

下面看看普通人和高手的回答!

普通人:

Kafka怎麼避免重複消費就是我們可以通過 我們可以在那個訊息消費的這一端就是我們可以用類似於分散式鎖的這樣一個設計吧。

我消費一個訊息的時候我可以直接用比如說redis裡面的setNx這樣一個指令,然後去把那個訊息儲存到redis裡面然後後面再如果重複傳送的話那我就直接只要去判斷這個Redis裡面有沒有存在就好了。

高手:

好的,關於這問題,我從幾個方面來回答。

首先Kafka Broker上儲存的訊息,都有一個Offset標記。

然後kafka的消費者是通過offSet標記來維護當前已經消費的資料,

每消費一批資料,Kafka Broker就會更新OffSet的值,避免重複消費。

image-20220513132307557

預設情況下,訊息消費完以後,會自動提交Offset的值,避免重複消費。

Kafka消費端的自動提交邏輯有一個預設的5秒間隔,也就是說在5秒之後的下一次向Broker拉取訊息的時候提交。

所以在Consumer消費的過程中,應用程式被強制kill掉或者當機,可能會導致Offset沒提交,從而產生重複提交的問題。

除此之外,還有另外一種情況也會出現重複消費。

在Kafka裡面有一個Partition Balance機制,就是把多個Partition均衡的分配給多個消費者。

Consumer端會從分配的Partition裡面去消費訊息,如果Consumer在預設的5分鐘內沒辦法處理完這一批訊息。

就會觸發Kafka的Rebalance機制,從而導致Offset自動提交失敗。

而在重新Rebalance之後,Consumer還是會從之前沒提交的Offset位置開始消費,也會導致訊息重複消費的問題。

image-20220513140121369

基於這樣的背景下,我認為解決重複消費訊息問題的方法有幾個。

  1. 提高消費端的處理效能避免觸發Balance,比如可以用非同步的方式來處理訊息,縮短單個訊息消費的市場。或者還可以調整訊息處理的超時時間。還可以減少一次性從Broker上拉取資料的條數。
  2. 可以針對訊息生成md5然後儲存到mysql或者redis裡面,在處理訊息之前先去mysql或者redis裡面判斷是否已經消費過。這個方案其實就是利用冪等性的思想。

以上就是我對這個問題的理解。

總結

重複消費這個問題很重要,如果沒有考慮到就會出現線上的資料問題。

所以在面試的時候,這些問題也能夠考察求職者的技術能力以及實踐能力。

另外,關於冪等性的問題,我在前面的視訊裡面有講,大家可以自己找一找。

喜歡我的作品的小夥伴記得點贊和收藏加關注。

file

版權宣告:本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Mic帶你學架構
如果本篇文章對您有幫助,還請幫忙點個關注和贊,您的堅持是我不斷創作的動力。歡迎關注「跟著Mic學架構」公眾號公眾號獲取更多技術乾貨!

相關文章