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 端不會丟訊息。
但 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 | 手動提交消費位移 |