消息中間件:Kafka

mq使用的目的

  • 應用解耦:屏蔽實現細節、異步通信,升級、擴容互不影響
  • 流量消峯:生產速率>消息速率、消息積壓能力、秒殺系統、批量導入
  • 消息廣播
  • 最終一致性

kafka多實例、多分區、多副本:

1、說明:

kafka實例:有四個Broker(四個kafka實例),多實例保證一個broker掛了,整個集羣還能繼續使用,高可用;

該topic有三個分區:part0,part1,part2,多分區,可以並行、併發比如寫入消息到某一個topic,高吞吐量;

每個分區有兩個副本,比如part0,在Broker2和Broker3中有兩個副本(follower),在Broker1中的part0是leader,負責與生產者、消費者進行消息的生產和消費;leader分區還有一個任務就是將自己收到的消費同步到他的兩個副本中;多副本保障的也是高可用,不至於因爲一個副本的丟失導致整個消息的丟失;

2、意義:

一個topic,爲什麼要有多個part:爲了方便多個生產者忘多個part併發寫入消息,提供吞吐量;

一個part,爲什麼要有多個副本:爲了防止某個broker宕機,導致消息的丟失,提高可用性;

 

幾個名詞

ISR(In-Sync Replicas):副本 同步隊列,

OSR(Outof-Sync Replicas):副本 非同步隊列

AR(Assigned Replicas)= ISR+OSR

我們知道副本數對Kafka的吞吐率是有一定的影響,但極大的增強了可用性。所有的副本(replicas)統稱爲Assigned Replicas,即AR。ISR是AR中的一個子集,由leader維護ISR列表,follower從leader同步數據有一些延遲,任意一個超過閾值都會把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也會先存放在OSR中,即AR=ISR+OSR。

HW(HighWatermark):consumer能夠看到的此partition的位置,即消費者能消費到的消息,消費者可見的消息,這個涉及到多副本的概念,取一個partition對應的ISR中最小的LEO作爲HW,consumer最多隻能消費到HW所在的位置。

LEO(LogEndOffset):表示每個partition的log最後一條Message的位置。

下圖詳細的說明了當producer生產消息至broker後,ISR以及HW和LEO的流轉過程:

由此可見,Kafka的複製機制既不是完全的同步複製,也不是單純的異步複製。事實上,同步複製要求所有能工作的follower都複製完,這條消息纔會被commit,這種複製方式極大的影響了吞吐率。而異步複製方式下,follower異步的從leader複製數據,數據只要被leader寫入log就被認爲已經commit,這種情況下如果follower都還沒有複製完,落後於leader時,突然leader宕機,則會丟失數據。而Kafka的這種使用ISR的方式則很好的均衡了確保數據不丟失以及吞吐率。一條消息只有被ISR中的所有follower都從leader複製過去纔會被認爲已提交。這樣就避免了部分數據被寫進了leader,還沒來得及被任何follower複製就宕機了,而造成數據丟失。而對於producer而言,它可以選擇是否等待消息commit,這可以通過request.required.acks來設置。這種機制確保了只要ISR中有一個或者以上的follower,一條被commit的消息就不會丟失。

Consumer Group:同樣是邏輯上的概念,是Kafka實現單播和廣播兩種消息模型的手段。同一個topic的數據,會廣播給不同的group;同一個group中的worker,只有一個worker能拿到這個數據。換句話說,對於同一個topic,每個group都可以拿到同樣的所有數據,但是數據進入group後只能被其中的一個worker消費。group內的worker可以使用多線程或多進程來實現,也可以將進程分散在多臺機器上,worker的數量通常不超過partition的數量,且二者最好保持整數倍關係,因爲Kafka在設計時假定了一個partition只能被一個worker消費(同一group內)。

Consumer Group延伸論述

 

什麼是消費者組

什麼是consumer group? 一言以蔽之,consumer group是kafka提供的可擴展且具有容錯性的消費者機制。既然是一個組,那麼組內必然可以有多個消費者或消費者實例(consumer instance),它們共享一個公共的ID,即group ID。組內的所有消費者協調在一起來消費訂閱主題(subscribed topics)的所有分區(partition)。當然,每個分區只能由同一個消費組內的一個consumer來消費。理解consumer group記住下面這三個特性就好了:

  • consumer group下可以有一個或多個consumer instance,consumer instance可以是一個進程,也可以是一個線程
  • group.id是一個字符串,唯一標識一個consumer group
  • consumer group下訂閱的topic下的每個分區只能分配給某個group下的一個consumer(當然該分區還可以被分配給其他group)

消費者位置(consumer position) 

消費者在消費的過程中需要記錄自己消費了多少數據,即消費位置信息。在Kafka中這個位置信息有個專門的術語:位移(offset)。很多消息引擎都把這部分信息保存在服務器端(broker端)。這樣做的好處當然是實現簡單,但會有三個主要的問題:1. broker從此變成有狀態的,會影響伸縮性;2. 需要引入應答機制(acknowledgement)來確認消費成功。3. 由於要保存很多consumer的offset信息,必然引入複雜的數據結構,造成資源浪費。而Kafka選擇了不同的方式:每個consumer group保存自己的位移信息,那麼只需要簡單的一個整數表示位置就夠了;同時可以引入checkpoint機制定期持久化,簡化了應答機制的實現。

 

 

 

 

kafka日誌文件結構:鏈接:Kafka文件存儲機制那些事

 

下面示意圖形象說明了partition中文件存儲方式:
image

                              圖1
  • 每個partion(目錄)相當於一個巨型文件被平均分配到多個大小相等segment(段)數據文件中。但每個段segment file消息數量不一定相等,這種特性方便old segment file快速被刪除。
  • 每個partiton只需要支持順序讀寫就行了,segment文件生命週期由服務端配置參數決定。

這樣做的好處就是能快速刪除無用文件,有效提高磁盤利用率。

partiton中segment文件存儲結構

讀者從2.2節瞭解到Kafka文件系統partition存儲方式,本節深入分析partion中segment file組成和物理結構。

  • segment file組成:由2大部分組成,分別爲index file和data file,此2個文件一一對應,成對出現,後綴".index"和“.log”分別表示爲segment索引文件、數據文件.
  • segment文件命名規則:partion全局的第一個segment從0開始,後續每個segment文件名爲上一個segment文件最後一條消息的offset值。數值最大爲64位long大小,19位數字字符長度,沒有數字用0填充。

下面文件列表是筆者在Kafka broker上做的一個實驗,創建一個topicXXX包含1 partition,設置每個segment大小爲500MB,並啓動producer向Kafka broker寫入大量數據,如下圖2所示segment文件列表形象說明了上述2個規則:
image

            圖2

以上述圖2中一對segment file文件爲例,說明segment中index<—->data file對應關係物理結構如下:
image

            圖3

上述圖3中索引文件存儲大量元數據,數據文件存儲大量消息,索引文件中元數據指向對應數據文件中message的物理偏移地址。
其中以索引文件中元數據3,497爲例,依次在數據文件中表示第3個message(在全局partiton表示第368772個message)、以及該消息的物理偏移地址爲497。

 

 

 

 

參考:

深度分析kafka可靠性良心好文:kafka數據可靠性深度解讀

深入分析消費組良心好文:消費組詳解

消費組&&topic多分區的分配詳解,真心好文好文,深入且易懂:kafka中partition和消費者對應關係

 

 

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