Kafka數據可靠性保證-ack,ISR,HW


爲保證producer發送的數據,能可靠的發送到指定的topic,topic的每個partition收到producer發送的數據後,都需要向producer發送ack(acknowledgement確認收到),如果producer收到ack,就會進行下一輪的發送,否則重新發送數據。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dI9yJSYO-1592709803258)(img/1567495818054.png)]

1.副本數據同步策略

方案 優點 缺點
半數以上follower完成同步,就發送ack 延遲低(follower同步有快有慢,半數以上同步完成就發送ack能把滿的那些給過濾掉) 選舉新的leader時,容忍n臺節點的故障,需要2n+1個副本(半數以上參與投票表示需要n+1臺節點存活,總共則需要n+1+n個副本)
全部的follower完成同步,才發送ack 選舉新的leader時,容忍n臺節點的故障,需要n+1個副本 延遲高(同步快的需要等同步滿的,導致延遲高)

Kafka選擇了第二種方案(全部完成同步,才發送ack),原因如下:

  1. 同樣爲了容忍n臺節點的故障,第一種方案需要2n+1個副本,而第二種方案只需要n+1個副本,而Kafka的每個分區都有大量的數據,第一種方案會造成大量數據的冗餘。
  2. 雖然第二種方案的網絡延遲會比較高,但網絡延遲對Kafka的影響較小。

2.ISR,AR

採用第二種方案之後,設想以下情景:leader收到數據,所有follower都開始同步數據,但有一個follower,因爲某種故障,遲遲不能與leader進行同步,那leader就要一直等下去,直到它完成同步,才能發送ack。這個問題怎麼解決呢?

Leader維護了一個動態的in-sync replica set (ISR-同步副本列表),意爲和leader保持同步的follower集合。當ISR中的follower完成數據的同步之後,leader就會給follower發送ack。如果follower長時間未向leader同步數據,則該follower將被踢出ISR,該時間閾值由replica.lag.time.max.ms參數設定。Leader發生故障之後,就會從ISR中選舉新的leader。

  • ISR(In-Sync Replicas ):與leader保持同步的follower集合

  • AR(Assigned Replicas):分區的所有副本

ISR是由leader維護,follower從leader同步數據有一些延遲(包括延遲時間replica.lag.time.max.ms和延遲條數replica.lag.max.messages兩個維度, 當前最新的版本0.10.x中只支持replica.lag.time.max.ms這個維度),任意一個超過閾值都會把follower剔除出ISR, 存入**OSR(Outof-Sync Replicas)**列表,新加入的follower也會先存放在OSR中。AR=ISR+OSR。

3.ack應答機制

對於某些不太重要的數據,對數據的可靠性要求不是很高,能夠容忍數據的少量丟失,所以沒必要等ISR中的follower全部接收成功。

所以Kafka爲用戶提供了三種可靠性級別,用戶根據對可靠性和延遲的要求進行權衡,選擇以下的配置。

acks參數配置:

  • 0:producer不等待broker的ack,這一操作提供了一個最低的延遲,broker一接收到還沒有寫入磁盤就已經返回,當broker故障時有可能丟失數據

  • 1:producer等待broker的ack,partition的leader落盤成功後返回ack,如果在follower同步成功之前leader故障,而由於已經返回了ack,系統默認新選舉的leader已經有了數據,從而不會進行失敗重試,那麼將會丟失數據

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rAMnW1y4-1592709803260)(img/1567496051181.png)]

  • -1(all):producer等待broker的ack,partition的leader和follower全部落盤成功後才返回ack。但是如果在follower同步完成後,broker發送ack之前,leader發生故障,導致沒有返回ack給Producer,由於失敗重試機制,又會給新選舉出來的leader發送數據,造成數據重複

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-w0W0EskW-1592709803261)(img/1567496113768.png)]

4. HW,LEO,LSO,LW名詞解釋

上圖表示一個日誌文件,這個日誌文件中只有9條消息,第一條消息的offset(LogStartOffset)爲0,最後一條消息的offset爲8,offset爲9的消息使用虛線表示的,代表下一條待寫入的消息。日誌文件的 HW 爲6,表示消費者只能拉取offset在 0 到 5 之間的消息,offset爲6的消息對消費者而言是不可見的。

  • LEO(log end offset):標識當前日誌文件中已寫入消息的最後一條的下一條待寫入的消息的offset。上圖中offset爲9的位置即爲當前日誌文件的 LEO,LEO 的大小相當於當前日誌分區中最後一條消息的offset值加1.分區 ISR 集合中的每個副本都會維護自身的 LEO ,而 ISR 集合中最小的 LEO 即爲分區的 HW,對消費者而言只能消費 HW 之前的消息。

  • HW(High Watermark):所有副本中最小的LEO, 一個分區中所有副本最小的offset,取一個partition對應的ISR中最小的LEO作爲HW,consumer最多隻能消費到HW所在的位置上一條信息

    注意:HW/LEO這兩個都是指已寫入消息的最後一條的下一條的位置而不是指最後一條的位置。

  • LSO(Last Stable Offset): 對未完成的事務而言,LSO 的值等於事務中第一條消息的位置(firstUnstableOffset),對已完成的事務而言,它的值同 HW 相同

  • LW(Low Watermark): 低水位, 代表 AR(分區中的所有副本)集合中最小的 logStartOffset 值

注意: LogStartOffset不可以縮寫爲LSO,因爲在Kafka中,LSO特指LogStableOffset

5.故障處理細節

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-trWEmKGq-1592709803264)(img/1567496203037.png)]

1.follower故障

follower發生故障後會被臨時踢出ISR,待該follower恢復後,follower會讀取本地磁盤記錄的上次的HW,並將log文件高於HW的部分截取掉,從HW開始向leader進行同步。等該follower的LEO大於等於該Partition的HW,即follower追上leader之後,就可以重新加入ISR了。

2.leader故障

leader發生故障之後,會從ISR中選出一個新的leader,之後,爲保證多個副本之間的數據一致性,其餘的follower會先將各自的log文件高於HW的部分截掉,然後從新的leader同步數據。

注意:這隻能保證副本之間的數據一致性,並不能保證數據不丟失或者不重複。

6.ISR 集合和 HW、LEO的關係

下面具體分析一下 ISR 集合和 HW、LEO的關係。

假設某分區的 ISR 集合中有 3 個副本,即一個 leader 副本和 2 個 follower 副本,此時分區的 LEO 和 HW 都分別爲 3 。消息3和消息4從生產者出發之後先被存入leader副本。

在這裏插入圖片描述
在消息被寫入leader副本之後,follower副本會發送拉取請求來拉取消息3和消息4進行消息同步。

在同步過程中不同的副本同步的效率不盡相同,在某一時刻follower1完全跟上了leader副本而follower2只同步了消息3,如此leader副本的LEO爲5,follower1的LEO爲5,follower2的LEO 爲4,那麼當前分區的HW取最小值4,此時消費者可以消費到offset0至3之間的消息。

當所有副本都成功寫入消息3和消息4之後,整個分區的HW和LEO都變爲5,因此消費者可以消費到offset爲4的消息了

由此可見kafka的複製機制既不是完全的同步複製,也不是單純的異步複製。事實上,同步複製要求所有能工作的follower副本都複製完,這條消息纔會被確認已成功提交,這種複製方式極大的影響了性能。而在異步複製的方式下,follower副本異步的從leader副本中複製數據,數據只要被leader副本寫入就會被認爲已經成功提交。在這種情況下,如果follower副本都還沒有複製完而落後於leader副本,然後leader副本宕機,則會造成數據丟失。kafka使用這種ISR的方式有效的權衡了數據可靠性和性能之間的關係。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章