Kafka 中的 冪等性(Idempotence) 是生產者端的重要機制,旨在確保即使在網絡抖動、重試、Broker 重啟等情況下,同一條消息不會被重復寫入到 Topic 中。這是實現可靠消息傳遞、避免重復消費的關鍵手段之一。
? 什么是冪等性?
簡單說:無論一個操作執行多少次,結果都是一樣的。
在 Kafka 中,冪等性意味著:
相同的消息,即使發送多次,也只會被寫入一次,且不會重復出現在日志中。
? Kafka 冪等性的作用場景
生產者可能會因為以下情況 重試發送 消息:
- 網絡超時,未收到 Broker 的 ack;
- Kafka Broker 重啟;
- 客戶端主動重試(
retries > 0
); - Leader 重新選舉。
這些重試可能會導致:同一條消息寫入多次,從而帶來“重復消費”的問題。
Kafka 的冪等性功能可以自動解決這個問題,不用你在應用層手動做去重。
? 如何開啟冪等性?
從 Kafka 0.11 版本開始支持冪等性。
? 開啟方式
從 Kafka 2.0 版本之后,冪等性可以通過如下方式開啟:
Properties props = new Properties();
props.put("enable.idempotence", "true"); // ? 顯式開啟
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
注意:
acks=all
是開啟冪等性的默認要求。- Kafka 2.5+ 中,
enable.idempotence
默認就是 true。
? Kafka 是如何實現冪等性的?
Kafka 利用了以下幾個機制:
1. Producer ID(PID)
- 每個生產者初始化時,Kafka 分配一個唯一的
PID
(Producer ID)。 - Kafka 會記住這個 PID 發給哪個 Partition 了哪些消息。
2. Sequence Number(序列號)
- Kafka 給每個消息分配一個自增的
Sequence Number
,每個 Partition 單獨維護。 - Broker 在每個 Partition 中,記錄下最近收到的 PID 和對應的序號。
? Kafka 判斷是否是重復消息的規則:
如果某個 PID + Partition 下,收到一條消息,其 Sequence Number 是重復的或小于上一次的,說明是重試的重復消息,Kafka 會自動丟棄它。
? 冪等性 vs 事務,有什么區別?
特性 | 冪等性(Idempotence) | 事務(Transaction) |
---|---|---|
作用 | 避免消息重復寫入 | 保證多條消息的原子提交 |
粒度 | 單條消息 | 一組消息 |
范圍 | 單個 partition、單個 producer | 多 partition、消費者偏移、多個 Topic |
是否有回滾 | ? 無 | ? 有 |
消費者是否感知 | ? 不感知 | ? read_committed 下感知 |
可以理解為:
冪等性是事務的基礎。Kafka 啟用事務時,會自動啟用冪等性,但單獨開啟冪等性不等于開啟事務。
? 使用冪等性的推薦配置
enable.idempotence=true ? 開啟冪等性
acks=all ? 所有副本都要確認
retries=Integer.MAX_VALUE ? 無限重試,確保最終寫入成功
max.in.flight.requests.per.connection=1(舊版本)? 限制同時請求數,確保順序(Kafka 2.4+ 可放寬為5)
?? 若你設置 max.in.flight.requests.per.connection > 1
,在舊版本 Kafka(<2.4)中可能會造成亂序+重復寫入,不再冪等。
? 總結一句話
Kafka 冪等性 = 在網絡失敗或客戶端重試時,確保消息只被寫入一次,自動去重,避免重復消費問題。
它是 實現可靠消息系統的第一步,在開啟事務或處理金融、支付等關鍵數據時非常重要。