1. 程式人生 > 其它 >kafka:(1) 整體架構

kafka:(1) 整體架構

  一個典型的 Kafka 體系架構包括若干 Producer、若干 Broker、若干 Consumer,以及一個ZooKeeper叢集。其中ZooKeeper是Kafka用來負責叢集元資料的管理、控制器的選舉等操作的。Producer將訊息傳送到Broker,Broker負責將收到的訊息儲存到磁碟中,而Consumer負責從Broker訂閱並消費訊息。

  

一、生產者

  生產者在預設情況下把訊息均衡地分佈到主題的所有分割槽上,而並不關心特定訊息會被寫到哪個分割槽。不過,在某些情況下,生產者會把訊息直接寫到指定的分割槽。這通常是通過訊息鍵和分割槽器來實現的,分割槽器為鍵生成一個雜湊值,並將其對映到指定的分割槽上。這樣可以保證包含同一個鍵的訊息會被寫到同一個分割槽上。生產者也可以使用自定義的分割槽器,根據不同的業務規則將訊息對映到分割槽。

二、消費者

消費者:消費者訂閱一個或多個主題,並按照訊息生成的順序讀取它們。消費者通過檢查訊息的偏移量來區分已經讀取過的訊息。

偏移量:偏移量是一個不斷遞增的整數值,在建立訊息時,Kafka會把它新增到訊息裡。在給定的分割槽裡,每個訊息的偏移量都是唯一的。消費者把每個分割槽最後讀取的訊息偏移量儲存在Zookeeper或Kafka上,如果消費者關閉或重啟,它的讀取狀態不會丟失。

消費者群組:消費者是消費者群組的一部分,會有一個或多個消費者共同讀取一個主題。群組保證每個分割槽只能被一個消費者使用。一個消費者失效,群組裡的其他消費者可以接管失效消費者的工作。

三、broker

  一個獨立的Kafka伺服器被稱為broker。broker接收來自生產者的訊息,為訊息設定偏移量,並提交訊息到磁碟儲存。broker為消費者提供服務,對讀取分割槽的請求作出響應,返回已經提交到磁碟上的訊息。根據特定的硬體及其效能特徵,單個broker可以輕鬆處理數千個分割槽以及每秒百萬級的訊息量。


  broker是叢集的組成部分。每個叢集都有一個broker同時充當了叢集控制器的角色(自動從叢集的活躍成員中選舉出來)。控制器負責管理工作,包括將分割槽分配給broker和監控broker。在叢集中,一個分割槽從屬於一個broker,該broker被稱為分割槽的首領。一個分割槽可以分配給多個broker,這個時候會發生分割槽複製。這種複製機制為分割槽提供了訊息冗餘,如果有一個broker失效,其他broker可以接管領導權。

  保留訊息:Kafka broker預設的訊息保留策略是這樣的:要麼保留一段時間(比如7天),要麼保留到訊息達到一定大小的位元組數(比如1GB)。當訊息數量達到這些上限時,舊訊息就會過期並被刪除,所以在任何時刻,可用訊息的總量都不會超過配置引數所指定的大小。

四、主題、分割槽

  kafka的訊息通過主題進行分類,主題可以被分為若干個分割槽,訊息以追加的方式寫入分割槽,然後以先入先出的順序讀取。由於一個主題包含幾個分割槽,因此無法在整個主題範圍內保證訊息的順序,但可以保證訊息在單個分割槽內的順序。
  同一主題下的不同分割槽包含的訊息是不同的,分割槽在儲存層面可以看作一個可追加的日誌(Log)檔案,訊息在被追加到分割槽日誌檔案的時候都會分配一個特定的偏移量(offset)。offset是訊息在分割槽中的唯一標識,Kafka通過它來保證訊息在分割槽內的順序性,不過offset並不跨越分割槽,也就是說,Kafka保證的是分割槽有序而不是主題有序。

  

  如圖,主題中有 4 個分割槽,訊息被順序追加到每個分割槽日誌檔案的尾部。Kafka中的分割槽可以分佈在不同的伺服器(broker)上,也就是說,一個主題可以橫跨多個broker,以此來提供比單個broker更強大的效能。

1、broker配置

  • log.dirs:Kafka把所有的訊息都儲存到磁碟上,存放這些日誌片段的目錄是通過 log.dirs來指定的。
  • auto.create .topics.enable:預設情況下,Kafka會在如下幾種情形下自動建立主題

    當一個生產者開始往主題寫入訊息時。
    當一個消費者開始從主題讀取訊息時。
    當任意一個客戶端向主題傳送元資料請求時。

  • num.partitions:指定了新建立的主題將包含多少個分割槽。注意,我們可以增加主題分割槽的個數,但不能減少分割槽的個數。
  • log.retention.hours:決定資料可以被保留的時間,預設168小時,也就是一週。通過檢查磁碟上日誌片段檔案的最後修改時間來實現的,一般指日誌片段的關閉時間。
  • log.retention.bytes:通過保留的位元組數來判斷訊息是否過期,作用在每個分割槽上,例如,如果一個包含8個分割槽的主題,log.retention.bytes被設為1GB,那麼這個主題最多可以保留8GB的資料,所以當主題的分割槽個數增加時,整個主題可以保留的資料也隨之增加。如果同時指定了log.retention.bytes和log.retention.ms,只要任意一個條件滿足,訊息就會被刪除。
  • log.segment.bytes:當日志片段大小達到log.segment.bytes指定的上限時(預設1GB),當前日誌片段就會被關閉,一個新的日誌片段被開啟。如果一個日誌片段被關閉,就開始等待過期。這個引數的值越小,就會越頻繁地關閉和分配新檔案,從而降低磁碟寫入的整體效率。過大可能會導致很長一段時間才能填滿一個日誌片段。
  • log.segment.ms:控制日誌片段關閉時間,指定了多長時間之後日誌片段會被關閉。
  • message.max.bytes:限制單個訊息的大小,預設1MB,如果生產者嘗試傳送的訊息超過這個大小,不僅訊息不會被接收,還會收到broker返回的錯誤資訊。值過大會導致負責處理網路連線和請求的執行緒花更多的時間來處理這些請求,增大磁碟寫入塊的大小,影響IO吞吐量。消費者客戶端設定的fetch.message.max.bytes必須與伺服器端設定的訊息大小進行協調。如果這個值比message.max.bytes小,那麼消費者就無法讀取比較大的訊息,導致出現消費者被阻塞的情況。

2、broker首領

  叢集裡第一個啟動的 broker 通過在 Zookeeper 裡建立一個臨時節點/controuer 讓自己成為控制器。 其他 broker 在啟動時也會嘗試建立這個節點,不過它們會收到一個“節點已存在”的異常,然後“意 識”到控制器節點已存在, 也就是說叢集裡已經有一個控制器了 。 其他 broker 在控制器節點上建立 Zookeeperwatch 物件,這樣它們就可以收到這個節點 的變更通知。這種方式可以確保叢集裡一次只有一個控制器存在。

  控制器其實就是一個 broker,只不過它除了具有一般 broker 的功能之外,還負責分割槽首領的選舉。

3、分割槽首領

  Kafka 為分割槽引入了多副本(Replica)機制,可通過增加副本數量來提升容災能力。同一分割槽的副本儲存的是相同的訊息(不過在同一時刻,副本之間並非完全一樣)。副本之間是 “一主多從” 的關係,其中 leader 副本負責處理讀寫請求,follower 副本只負責與 leader 副本的訊息同步。副本處於不同的broker中,當 leader 副本出現故障時,從 follower 副本中重新選舉新的 leader 副本對外提供服務。

4、消費者首領

  當消費者要加入群組時,它會向群組協調器傳送一個 JoinGroup 請求。第一個加入群組的消費者將成為“群主”。群主從協調器那裡獲得群組的成員列表(列表中包含了所有最近傳送過心跳的消費者,它們被認為是活躍的),並負責給每一個消費者分配分割槽。它使用一個實現了 PartitionAssignor介面的類來決定哪些分割槽應該被分配給哪個消費者。
  Kafka 內建了兩種分配策略。分配完畢之後,群主把分配情況列表傳送給群組協調器,協調器再把這些資訊傳送給所有消費者。每個消費者只能看到自己的分配資訊,只有群主知道群組裡所有消費者的分配資訊。這個過程會在每次再均衡時重複發生。

四、Zookeeper群組

  Kafka使用Zookeeper儲存叢集的元資料資訊和消費者資訊。Zookeeper使用的是一致性協議,建議每個群組裡應該包含奇數個節點,只有當群組裡的大多數節點處於可用狀態,Zookeeper才能處理外部的請求,但節點過多會降低整個群組的效能。