Kafka 數據重復 和數據丟失的情況及解決


一、生產者端

首先,我們要知道生產者在生產數據時是靠ack應答機制來傳輸數據的,當

ack=0時,生成者無需等待brokder的ack,一直發送消息

ack=1時,生產者接收到leader的ack信號,就會發送下一條數據

ack=-1時,生產者必須等到所有broker返回ack信號,才會發送下一條數據

1.1數據丟失的情況

當ack=0時,如果有一台broker掛掉,那么那台broker就會接收不到這條消息

當ack=1時,如果有一台follower掛掉,那么這台follower也會丟失這條消息,

      或者follower還未同步leader的數據,leader掛了,也會丟失消息

1.2數據重復的情況

當ack=-1時,只要有一台follower沒有與leader同步,生產者就會重新發送消息,這就照成了消息的重復

1.3避免方法

開啟精確一次性,也就是冪等性, 再引入producer事務 ,即客戶端傳入一個全局唯一的Transaction ID,這樣即使本次會話掛掉也能根據這個id找到原來的事務狀態

enable.idempotence=true

開啟后,kafka首先會讓producer自動將 acks=-1,再將producer端的retry次數設置為Long.MaxValue,再在集群上對每條消息進行標記去重!

去重原理:

在cluster端,對每個生產者線程生成的每條數據,都會添加由生產者id,分區號,隨機的序列號組成的標識符: (producerid,partition,SequenceId),通過標識符對數據進行去重!

但是只能當次會話有效,如果重啟了就沒有效果,所以需要事務的支持

二、消費者端

消費者是以維護offset的方式來消費數據的,所以如果在提交offset的過程中出問題,就會造成數據的問題,即已經消費了數據,但是offset沒提交

大佬博客里已經解釋很詳細了https://blog.csdn.net/qingqing7/article/details/80054281

 

 

 

注意:手動提交時,無論是同步提交還是異步提交,都會有數據重復消費的風險

解決方案:

1.手動維護offset

2.加大這個參數kafka.consumer.session.timeout,以避免被錯誤關閉的情況

3.加大消費能力

4.在下游對數據進行去重

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM