跳轉到

Kafka 訊息「零遺失」

Producer

為了確保 producer 的訊息有到達 Broker,需要設置的 producer configuration parameters:

parameter value description
acks all 只有當成功寫入到所有副本分區時,才會成功
retries 重試次數
retry.backoff.ms 訊息發送逾時或失敗後,重試的間隔。

Warning

在 broker 沒有正常回應的情況下,由於重試機制會導致 producer 重複發送訊息。因此若要 exactly once,處理訊息的 business logic 必須具備冪等性。

Broker

broker 端接收到生產端的訊息後,成功應答生產端後,訊息會遺失嗎? 如果 broker 能像 mysql 伺服器一樣,在成功應答給客戶端前,能把訊息寫入到了磁碟進行持久化,並且在當機斷電後,有恢復機制,那麼我們能說 broker 端不會丟訊息。

img

但 broker 端提供資料不丟的保障和 mysql 是不一樣的。broker 端在接受了一批訊息資料後,是不會馬上寫入磁碟的,而是先寫入到 page cache 裡,這個 page cache 是 ​​ 作業系統的頁快取(也就是另一個內存,只是由作業系統管理,不屬於 JVM 管理的記憶體),透過定時或定量的的方式( log.flush.interval.messages 和 log.flush.interval.ms)把 page cache 裡的資料寫入磁碟。

如果 page cache 在持久化到磁碟前,broker 進程當機了,這時候不會遺失訊息,重啟 broker 即可;

但如果此時作業系統當機或實體機當機了,page cache 裡的資料還沒有持久化到磁碟裡,此種情況資料就遺失了。

kafka 應對此種情況,建議是透過多副本機制來解決。

需要設置的 broker configuration parameters:

parameter value description
default.replication.factor 3 分區副本數量
min.insync.replicas 2 為了回應 producer 成功寫入所需要的最小分區副本數量。
unclean.leader.election.enable false 沒有和 leader 分區保持資料同步的副本分區是否也能參與 leader 分區的選舉,如果允許,則有可能遺失尚未同步的資料。

Consumer

拉取訊息後,如果先提交消費位移,consumer 處理完 business logic 之前掛了就會導致訊息遺失。因此需要取消自動提交。

需要設置 consumer configuration parameters:

parameter value description
enable.auto.commit false 手動提交消費位移

Reference