1. 程式人生 > >kafka副本機制之數據可靠性

kafka副本機制之數據可靠性

require 有一個 leader 分配 興趣 sign bsp 集群 可用

一、概述

  為了提升集群的HA,Kafka從0.8版本開始引入了副本(Replica)機制,增加副本機制後,每個副本可以有多個副本,針對每個分區,都會從副本集(Assigned Replica,AR)中,選取一個副本作為Leader副本,所有讀寫請求都由Leader副本處理,其余的副本被稱為Follwer副本,其會從Leader副本拉取消息更新到本地。因此,Follower更像是Leader的熱備。

  一般情況下,同一個分區的多個副本會被均勻的分配到集群中的不同Broker上,當leader副本所在機器出現故障後會重新選舉出新的leader實現故障轉移。(針對副本如何分配以避免單臺機器上leader過多導致集群負載均衡不均及多副本在同一機器上等問題,不再本文的討論範圍內,感興趣的小夥伴,可以參考下kafka-reassign-partitions腳本)。


二、關鍵術語

  • 副本:kafka對消息的冗余存儲以提升容災能力,以分區為單位。
  • Leader副本:每個分區都有多個副本,針對每個分區,都有一個唯一的一個Leader副本,負責該分區的讀寫請求處理。
  • Follower副本:從Leader副本拉取數據,作為Leader副本的熱備。
  • AR:(Assigned Replica)副本集合(Leader+Follower的總和)
  • ISR:(In-Sync Replica)同步副本集合,與leader副本消息鏡像“相差”不多的副本集合,又稱為“核心副本集”,與kafka 發送端的ACK的幾種語義有關,後面會詳聊(註意這個集合是動態的,是會剔除和新增的)。
  • HW:(High Watermark)是一個特殊的標記,與ISR有關,用以標記該分區中哪些消息被“commit”了,自然的對於消費者來說,它只能看到被commit了的消息,也就是HW之前的消息,當ISR集合中的副本都從Leader拉取了HW之後的某些消息後,Leader才會遞增HW,因此HW的概念僅存在與Leader副本中,Follower不存在這個概念。
  • 有的小夥伴可能會問了,那為何要有這個標記呢,這個標記是為了從語義的角度保證即使Leader副本所在的機器宕機了,也不會出現消息丟失,後面會詳細介紹。
  • LEO:(Log End Offset)每個分區都會有的一個標記,標示當前分區的最後一條消息(針對Leader就是Leader上的最後一條消息,針對某個Follower,就是當前該Follower的最後一條消息)

三、圖解AR、ISR、HW、LEO

這裏我們假設每個副本有三個分區,副本被剔除和加入ISR的臨界條件為落後leader 三條消息,kafka判斷是否符合ISR的條件有兩個:

  • Follower落後leader多少條消息,落後超過配置值後將踢出ISR
  • Follwer多久沒從leader同步消息,超過配置時間沒拉取數據將從ISR踢出(kafka0.9後刪除了該判斷,a為唯一判斷標準)。

下面我們用圖來表達下上面的概念的關系:

  1. 時刻t1該分區的情況如下,此時ISR與AR一致(Leader,follower1,follower2),follower2 和 leader的消息一致,LEO都為4,follower1的LEO為2,因此leader的HW為2.技術分享圖片
  2. .時刻t2 follower full gc.技術分享圖片
  3. 時刻t3,leader接受producer發送來的2條消息5、6,此時發現Follower1已經落後了自己4條消息,將follower1踢出ISR集合技術分享圖片
  4. 時刻t4,follower2 從leader拉取到5這條消息,更新HW值。技術分享圖片
  5. 時刻t5,follower1 full gc完成後,發現自己已經落後了很多消息,開始從leader追消息,待消息不落後leader太多時,申請加入ISR中。技術分享圖片

經過上面的圖解分析後,我們來看下幾個需要註意的點

  • ISR是AR的一個自己,並且是不斷伸縮的,變化的條件為“是否落後太多的消息”
  • HW之前的消息代表被集群“commit”的消息,只有commit的消息才對client端(consumer以及request.required.acks為-1時的producer),在前面我們說過,這樣能夠使kafka在語義上支持不丟消息。我們從producer和consumer兩個維度來分析:

  在這之前,我們先說下request.required.acks的取值範圍(1、0、-1)
  1:leader成功就返回
  0:無需等待leader響應
  -1:ISR都成功才返回

  1. 從producer的角度:當producer將request.required.acks設置為-1時候,保證了消息已經在多個副本中存在了,此時即便leader掛了,這個消息還是存在的(leader選舉會從ISR中選舉出新的leader),那麽假如ISR遲遲同步不成功怎麽辦呢?
  2. 從consumer的角度:如果沒有HW,consumer拉取到最新的消息後,而此時leader宕機,很有可能新的leader中並沒有此消息。

  當然不能保證消息永遠不會丟,極端的情況下,如ISR中只有leader的時候(當然可以配置集群可用的最小核心副本集個數,但會極大的損失可用性),或者所有副本都宕機了(這個。。。沒辦法。),消息還是會丟的。

kafka副本機制之數據可靠性