kafka如何保證數據可靠性

一、必須知道的專業名詞

kafka中,每個partition可以有多個副本(Replica),分爲leader、follower,正常情況下,客戶端只向leader發送數據、leader消費數據,follower的出現是爲了保證kafka數據的高可用和一致性,也是作爲災備的存在。再保證高可用的過程中,leader與follower進行數據同步時,產生的如下一些專業術語,都是基於partition之內的概念。爲了方便理解,假設以下所有的描述,都是基於某個只有一個partition,partition裏面有3個副本的topic。

  • HW(High Watermark)俗稱高水位,consumer能夠消費kafka的最大offset

  • LEO (Log End Offset)已經寫入kafka log中日誌的最大offset值加1

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

  • ISR (In Sync Replicas) 在kafka中,所有與leader保持數據同步的副本(Replica)

在這裏插入圖片描述

如上圖所示是HW與LEO的關係,每一個小塊表示一條消息,LEO的值永遠是大於HW的。我們消費kafka時,並不是producer往kafka寫多少,consumer就消費多少。HW是相對於Replica之間而言的,三個Replica,一個leader,兩個follower,當producer往kafka發數據時,在消息被寫入leader,leader收到數據後會與其它兩個follower保存數據同步。

在這裏插入圖片描述

如上圖所示,每個 follower同步的速度可能都不太一樣,某一時刻,leader已經寫入了7條消息,follow1可能同步了第6條消息,而follow2只同步了4條消息,這時的HW值也就是4,也就是經常說的“木桶效應”,以最低水位的那個follower爲準。

二、producer發送acks機制

acks機制是producer往kafka broker發數據時的一種回調機制,由於kafka多副本的特性,簡言之,這種機制實際是決定各個副本(leader和follower)與producer的回調策略,目的是確認消息是否發送成功,就像是log4j的日誌級別一樣,每個級別的要求不一樣。有如下三種級別:

  • acks=0:producer不會等待任何來自服務器的響應。

    如果當中出現問題,導致服務器沒有收到消息,那麼producer無從得知,會造成消息丟失

    由於producer不需要等待服務器的響應所以可以以網絡能夠支持的最大速度發送消息,從而達到很高的吞吐量

  • acks=1(默認值):只要集羣的Leader節點收到消息,生產者就會收到一個來自服務器的成功響應

    如果消息無法到達Leader節點(例如Leader節點崩潰,新的Leader節點還沒有被選舉出來)生產者就會收到一個錯誤響應,爲了避免數據丟失,生產者會重發消息

    如果一個沒有收到消息的節點成爲新Leader,消息還是會丟失

    此時的吞吐量主要取決於使用的是同步發送還是異步發送,吞吐量還受到發送中消息數量的限制,例如生產者在收到服務器響應之前可以發送多少個消息

  • acks=-1:只有當所有參與複製的節點全部都收到消息時,生產者纔會收到一個來自服務器的成功響應

    這種模式是最安全的,可以保證不止一個服務器收到消息,就算有服務器發生崩潰,整個集羣依然可以運行

三、leader選舉

leader的選舉先看回頭看上面ISR的定義。kafka每個topic的每個partition都會維護一個ISR列表存儲在zookeeper裏面,我們進入zk裏面,查看一個topic名爲test1,partition編號爲1的元數據信息,裏面的記錄了leader是編號爲1004的broker,ISR列表是【1004,1003,1005】,其中1003,1005也就是follower。

[zk: localhost:2181(CONNECTED) 7] get /brokers/topics/test1/partitions/1/state
{"controller_epoch":4,"leader":1004,"version":1,"leader_epoch":0,"isr":[1004,1003,1005]}
  • 怎樣才能定義爲ISR呢?

​ 舉個栗子,上述的1004,1003,1005中,三人賽跑,1004作爲leader跑在最前面,1003,1005作爲follower跑在後面緊追leader,假如規定一個距離10m,leader 一旦甩開任意一個follower超過10m的距離,則被甩掉的這個follower會被提出ISR列表,在實際生產中,通過設置broker的參數replica.lag.time.max.ms來控制這個距離。

  • leader掛了怎麼辦?

    根據優勝劣汰的原則,leader掛了,離leader最近的那個follower,會上位選舉成新的leader,因爲這個新的leader收到的消息最多

四、Consumer 消費一致性

世上沒有100%絕對可靠的系統。萬一kafka分區的某個leader節點掛了,還能保證消費者不重複消費,也不多消費嗎?

先回頭看上面的HW(High Watermark)定義,也就是consumer能夠消費的最,大offset。

爲驗證高可用性,我們來舉個反例。下圖中,虛線淡黃色的塊表示還未從leader同步的數據,按照我們上面說的,consumer只能消費HW線之前的數據。consumer正要消費record1-record3的時候,假設這時leader所在的broker突然掛了,“優勝劣汰”的原則,跑在前面的follower1會被選舉成新的leader。這時你可能會問?爲什麼不可以把follower1的最大值作爲HW,這樣可以消費到record4呢?再極端一點,假如follower1也同時掛了呢?如果以follower1的record4爲HW的話,當leader切換成follower2時,follower2並未收到最初始leader同步過來的record4,所以會造成丟數據!

綜上所述,HW必須是以跑的最慢的follower來定,HW機制也很好的保證了消費端的一致性,不會造成consumer少消費數據。但是,這樣換區的強一致性必將帶來性能上的損耗,很明顯的,性能一定的損耗在leader與follower直接的數據同步,這點損耗在大多數場景中還是可以接受的,換來的是kafka的高可用、一致性。

在這裏插入圖片描述

五、總結

kafka作爲一個高吞吐的分佈式發佈訂閱消息系統,在大數據應用中非常廣泛,可以說是實時計算的標配。它擁有一系列的優勢:高吞吐量、低延遲、可擴展性、持久性、可靠性、容錯性、高併發等等,滿足我們大多數非業務型的消息隊列系統,但是也有不少使用kafka用來處理業務型的數據,說明kafka在分佈式發佈訂閱消息系統的地位越來越高,越來越成熟。

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