Kafka重複消費、訊息丟失、訊息亂序
阿新 • • 發佈:2022-04-19
一、應用場景
- 大量掃碼/刷卡交易訂單日誌傳輸
- 日誌採集
二、產生原因
- 日誌採集客戶端(Producer):
- 超時重傳,日誌重複(enable.idempotence=false重複傳送)
- 訊息失敗,未持久化(acks=0不重試;或acks=1但leader閃退)
- 批量傳送,資料亂序(max.in.flight.requests.per.connection>1批量傳送)
- Kafka伺服器:
- OSR參與選舉,導致訊息丟失(unclean.leader.election.enable=true脫節選舉)
- ISR列表為1或空,未備份(min.insync.replicas<=1副本過少)
- 日誌處理應用(Consumer):
- 消費異常,訊息丟失(enable-auto-commit=true自動提交)
- 未提交Offset,重複消費(異常閃退和重平衡)
三、解決方案
-
日誌採集客戶端(Producer):
## 解決亂序問題 ## 批量傳送改為每次逐個傳送,預設5 max.in.flight.requests.per.connection=1 ## 解決重複生產 ## 每個ProducerId全域性唯一;ack=all和retries>1保證持久化 enable.idempotence=true ack=all retries=2 ## 轉移處理異常生產
-
Kafka伺服器:
## 解決資料丟失問題 ## 禁止OSR參與選取leader unclean.leader.election.enable=false ## ISR列表至少2個以上 min.insync.replicas=2
-
日誌處理應用(Consumer):
## 解決訊息丟失 ## 禁止自動提交 enable.auto.commit=false ## 重複消費 ## 介面冪等性;MySQL記錄每一個Offset消費狀態;
四、引數
引數 | 作用和優點 | 缺點 |
---|---|---|
max.in.flight.requests.per.connections=1 | 生產者傳送緩衝池(flight)只緩衝一個訊息記錄,避免亂序;類似同步佇列AQS,一次只能傳送一個 | 吞吐量下降 |
enable.idempotence=true | 生產者維護全域性唯一producerId,避免重複;類似主鍵,重複資料不會重複持久化 | retries=2配合 |
acks=all | 生產者要求Kafka持久化所有ISR,保證持久化;類似全同步複製 | ISR列表可能空或只有leader;min.insync.replicas=2配合 |
retries=2 | 生產者超時重發次數,保證持久化;類似超時重傳 | 可能造成重複持久化;enable.idempotence=true配合 |
unclean.leader.election.enable=false | Kafka中OSR引數競選Leader,保證Kafka高可用; | OSR訊息脫節,造成大量資料丟失;不開啟 |
min.insync.replicas=2 | Kafka中ISR至少2個,保證持久化;類似半同步複製 | acks=all配合 |
enable.auto.commit=false | 消費者關閉自動提交,避免訊息丟失;類似事務提交 | 需要額外維護Offset,容易造成重複消費,需要消費冪等性 |