1. 程式人生 > 其它 >Kafka重複消費、訊息丟失、訊息亂序

Kafka重複消費、訊息丟失、訊息亂序

一、應用場景

  • 大量掃碼/刷卡交易訂單日誌傳輸
  • 日誌採集

二、產生原因

  • 日誌採集客戶端(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,容易造成重複消費,需要消費冪等性