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

  • 2022 年 6 月 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學架構」公眾號公眾號獲取更多技術乾貨!