1. 程式人生 > >kafka ISR設計及水印與leader epoch副本同步機制深入剖析-kafka 商業環境實戰

kafka ISR設計及水印與leader epoch副本同步機制深入剖析-kafka 商業環境實戰

版權宣告:本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。版權宣告:禁止轉載,歡迎學習。QQ郵箱地址:[email protected],如有任何商業交流,可隨時聯絡。

1 帽子理論(Gilbert 和 Lynch )

  • 一致性

      any read operation that begins after a write operation completes must 
      return that value, or the result of a later write operation
    
      通過某個節點的寫操作結果對後面通過其它節點的讀操作可見
      
      強一致性:
      如果更新資料後,併發訪問情況下後續讀操作可立即感知該更新,稱為強一致性。
      
      弱一致性:
      如果允許之後部分或者全部感知不到該更新,稱為弱一致性。
      
      最終一致性:
      若在之後的一段時間(通常該時間不固定)後,一定可以感知到該更新,稱為最終一致性。
    複製程式碼
  • 可用性(Availability)

      every request received by a non-failing node in the system must result in a response
    
      任何一個沒有發生故障的節點必須在有限的時間內返回合理的結果。
    複製程式碼
  • 分割槽容忍性(Partition Tolerance)

      the network will be allowed to lose arbitrarily many messages sent from one node to another
    
      部分節點宕機或者無法與其它節點通訊時,各分割槽間還可保持分散式系統的功能。
    複製程式碼
  • 悖論總結:

    可用性限定在無論是否叢集節點宕機,只要有活著的節點,就會立即返回請求結果。若要限制返回結果必須是最近一次寫的結果,就比較悲劇,若允許分割槽容忍性 => 分散式系統分割槽之間就存在資料同步機制,那麼就有可能因為分割槽心跳切斷,導致資料不一致。

2 partition本質就是為了日誌備份(對外最小的儲存單元)

Kafka中topic的每個partition有一個預寫式的日誌檔案,雖然partition可以繼續細分為若干個segment檔案,但是對於上層應用來說可以將partition看成最小的儲存單元(一個有多個segment檔案拼接的“巨型”檔案),每個partition都由一些列有序的、不可變的訊息組成,這些訊息被連續的追加到partition中。

  • partition本質就是為了日誌備份,利用多份日誌檔案的副本(replica)備份來共同提供冗餘機制來保持系統的高可用性。
  • kafka會把副本均勻的分配到所有的Broker上。在其中所有的副本中,會挑選一個Leader副本來對外提供服務,其他的副本統稱為follower副本,只能被動的向leader副本請求資料。

3 Partitioner 三分天下

下圖展示了3個Partition把一個Topic主題資料流分成三份,通過Partioner路由依次追加到分割槽的末尾中。如果partition規則設定的合理,所有訊息可以均勻分佈到不同的partition裡,這樣就實現了水平擴充套件。

config/server.properties可以設定num.partitions引數,實現主題資料分流。

3 Leader副本競選上崗(in-sync replicas)

  • 每一個分割槽都存在一個in-sync replicas。
  • in-sync replicas集合中的每一個副本都與leader保持同步狀態,不在裡面的保持不了同步狀態。
  • 只有ISR中的副本才有資格被選為leader。
  • Producer寫入的訊息只有被ISR中的副本都接收到,才被視為"已提交"。

4 水印HW與末端位移LEO => Leader副本

  • 這裡著重強調一下,Leader副本水印HW才真正決定了對外可看到的訊息數量。
  • 所有的副本都有LEO和HW。
  • Leader副本水印HW的更新發生在所有的副本都更新了最新的LEO後,Leader副本最終才認為可以更新Leader副本水印。

5 ISR設計優化(replica.lag.max.messages廢棄)

  • 解決了producer突然發起一大波訊息,從而產生瞬時高峰流量。若設定replica.lag.max.messages=4,則follower副本會被瞬時的拉開距離,從而導致follower副本瞬間被踢出ISR。不過一段時間follower副本同步後,會再次進入ISR。
  • 同步不同步,同步不同步反覆出現,是多大的效能浪費。
  • 0.9.0.0開始採用 replica. lag. time. max. ms,預設是10s,可謂是明智之舉。

6 HW同步機制(Leader與follower的愛恨纏綿)

6.1 指哪打哪(HW指向哪裡?)

  • 這裡重點強調,都是無論HW還是LEO都是指向下一條訊息
  • 舉例如下:如果一個普通topic的某個分割槽副本的LEO是10,那麼該副本當前儲存了10條訊息,位移值範圍是[0, 9]。此時若有一個producer向該副本插入一條訊息,則該條訊息的位移值是10,而副本LEO值則更新成11。

6.2 Leader與follower的HW愛恨纏綿(兩階段請求定終身)

  • follower 副本會不斷地向leader副本傳送Fetch請求
(1)follower 副本物件何時更新LEO?
follower 副本專屬執行緒不斷地向leader副本所在broker傳送FETCH請求。

leader 副本傳送 FETCH response 給follower副本。

Follower 拿到response之後取出位移資料寫入到本地底層日誌中,在該過程中其LEO值會被更新。
複製程式碼
(2)leader 端非自己副本物件何時更新LEO?
leader 端非自己副本物件 LEO值是在leader端broker處理FETCH請求過程中被更新的。
複製程式碼
(3) follower 副本物件何時更新HW?
Follower 副本物件更新HW是在其更新本地LEO之後。

一旦follower向本地日誌寫完資料後它就會嘗試更新其HW值。
演算法為取本地LEO與FETCH response中HW值的較小值
複製程式碼
(4)leader 副本物件何時更新HW?
Leader 副本物件處理 Follower FETCH請求時在更新完leader 端非自己副本物件的LEO後將嘗試更新其自己HW值

producer 端寫入訊息會更新leader Replica的LEO

副本被踢出ISR時

某分割槽變更為leader副本後
複製程式碼
(5)兩階段請求定終身:

第一次fetch請求僅獲得了當前的資料,fetchOffset < Leader LEO, 因為leader 端的非自己的副本leo 是根據fetch請求確定的,因此,只有第二次請求時,fetchOffset才會和Leader LEO相等,進而更新 leader HW ,進而響應為 leader HW,進而更新 Folloer HW。

6.3 HW更新延遲帶來的刀山火海

  • 因為 fetchOffset是實實在在的需要位移。所以只有第二輪請求時,Follower才會在其現有位移的基礎上,加1進行請求,從而連鎖更新 會更新Leader非自己remoteLEO 和 Leader HW 和 Follower HW。
  • 刀山火海就在一輪請求和第二輪請求之間發生了。

7 刀山火海敬請期待

本文實在麻煩,大牛的技術部落格看起來總總有些詞不達意,我順便就直介面語化,希望帶來不同的效果。技術就是一層窗戶紙,看我把kafka和spark剖析的體無完膚。香港美景,一覽眾山小,技術道路上毅然前行!!

秦凱新 於深圳 201811230124

版權宣告:本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。版權宣告:禁止轉載,歡迎學習。QQ郵箱地址:[email protected],如有任何商業交流,可隨時聯絡。