為保證 producer 傳送的資料,能可靠的傳送到指定的 topic,topic 的每個 partition 收到 producer 發
送的資料後,都需要向 producer 傳送 ack(acknowledgement 確認收到),如果 producer 收到
ack,就會進行下一輪的傳送,否則重新傳送資料。
方案一:半數以上完成同步,就傳送ack
優點:低延遲
缺點:選舉新的leader時,容忍n臺節點的故障,需要2n+1臺副本
方案二:全部完成同步,才傳送ack
優點:選舉新的leader時,容忍n臺節點的故障,需要n+1臺副本
缺點:延遲高
kafka 選擇了第二種方案,原因如下:
1. 同樣為了容忍 n 臺節點的故障,第一種方案需要 2n+1 個副本,而第二種方案只需要 n+1個副本,
第一種方案會造成大量資料的冗餘。
2.雖然第二種方案的網路延遲會比較高,但網路延遲對kafka的影響較小
採用第二種方案之後,設想以下情景:leader 收到資料,所有 follower 都開始同步資料, 假如有乙個follower因為某種故障,遲遲不能與 leader 進行同步,那 leader就要一直等下去,直到它完成同步才能傳送 ack。如何破解這個問題呢?
leader 維護了乙個動態的 in-sync replica set (isr),意為和 leader 保持同步的 follower 集合。當 isr中的 follower 完成資料的同步之後,leader 就會給客戶端傳送 ack。如果 follower長時間未向leader同步資料,則該follower將被踢出isr,該時間 閾值由replica.lag.time.max.ms引數設定。leader 發生故障之後,就會從 isr 中選舉新的 leader。
並不是所有場景都需要資料完全可靠,例如某些日誌都是一些資料是可以容忍少量資料丟失的,所以沒
有必要等待isr中的 follower 全部接收成功在傳送ack。
因此kafka為使用者提供了三種可靠性級別,使用者根據對可靠性和延遲的要求進行權衡,自行選擇級別。
acks:
0:producer不等待broker的ack,提供了最低延遲,broker一接收到還沒有寫入磁碟就已經返回,當broker故障時可能丟失資料
1:producer等待broker的ack,partition的leader落盤成功後返回ack,如果在follower同步成功之前leader故障,那麼就會丟失資料
-1 or all:producer等待broker的ack,partition的leader和follower全部落盤成功後才返回ack,但是如果在follower同步成功後,broker傳送ack之前,leader發生故障,那麼會造成資料重複
follower發生故障後會被臨時踢出isr,待該follower恢復後,follower會讀取本地磁碟記錄的上次hw,並將log檔案高於hw的部分擷取掉,從hw開始向leader進行同步。等待follower的led大於等於該partition的hw,即follower追上leader之後,就可以重新加入isr
leader發生故障之後,會從isr中選出乙個新的leader,之後為保證多副本之間的資料一致性,其餘的follower會先將各自的log檔案高於hw的部分截掉,然後從新的leader同步資料。注意:這只能保證副本的之間的資料一致性,並不能保證資料不丟失和不重複
將伺服器的 ack 級別設定為-1,可以保證 producer 到 server 之間不會丟失資料,即 at least once語義。相對的,將伺服器 ack 級別設定為 0,可以保證生產者每條訊息只會被 傳送一次,即 at mostonce 語義。
即:ack=-1:at least once 不丟資料可能重複
ack=0:at most once 會丟資料,但不會重複
如何實現exactly once呢?
at least once + 下游系統自己處理冪等性=exactly once
0.11版本引入了一項重大特性:冪等性。所謂的冪等性就是指 producer 不論 向 server 傳送多少次重
復資料,server 端都只會持久化一條。冪等性結合 at least once 語 義,就構成了 kafka 的 exactly
once 語義。即:
at least once + 冪等性 = exactly once
要啟用冪等性,只需要將 producer 的引數中 enable.idompotence 設定為 true 即可。當true,acks預設all
kafka 的冪等性實現其實就是將原來下游業務需要做的去重放在了資料上游。開啟冪等性的 producer
在 初始化的時候會被分配乙個 pid,發往同一 partition 的訊息會附帶 sequence number。而 broker
端會對做快取,當具有相同主鍵的訊息提交時,broker 只 會持久化一條
但是 pid 重啟就會變化,同時不同的 partition 也具有不同主鍵,所以冪等性無法保證跨分割槽跨會話的
exactly once。
特別注意:所謂exactly once就是生產者發給kafka多少資料,kafka剛剛不多不少的儲存多少資料。
至於kafka能不能保證exactly once都根消費者沒關係。
基於at least once + 冪等性(下游或者kafka自己實現)無法實現跨會話的exactly once
Kafka如何保證資料可靠性
kafka的資料可靠性保證 1.副本資料同步策略 兩種副本資料同步策略 kafka選擇第二種 方案優點 缺點半數以上完成同步,就傳送ack 延遲低選舉新的leader時,容忍n臺節點的故障,需要2n 1個副本 全部完成同步,才傳送ack 選舉新的leader時,容忍n臺節點的故障,需要n 1個副本 ...
kafka保證資料可靠性的方式
kafka的以下幾個基本特性保證了基本的可靠性 生產者可以進行有關配置,使得不一定等到資料認為是已提交的之後,才進行下一輪的投遞,這是在可用性和一致性的之間的平衡 分割槽副本複製方式和同步條件 複製係數及其意義 replication.factor 複製係數,指定了乙個分割槽的副本個數,預設是3,意...
Kafka如何保證訊息的可靠性傳輸
1.消費端弄丟了資料 唯一可能導致消費者弄丟資料的情況,就是說,你消費到了這個訊息,然後消費者那邊自動提交了 offset,讓 kafka 以為你已經消費好了這個訊息,但其實你才剛準備處理這個訊息,你還沒處理,你自己就掛了,此時這條訊息就丟咯。這不是跟 rabbitmq 差不多嗎,大家都知道 kaf...