延續上篇提到的 Kafka 三本柱,我們再用一小篇的內容稍微補充點 Kafka 基礎但卻十分重要的概念與邏輯,包含 Kafka 是如何分類訊息,如何分發這個大量的數據卻不會亂套,是怎麼水平擴展它的吞吐量的,今天就來聊聊這些話題。
老樣子,在進入到技術概念的探討前,可以先用一個較為生活化的類比來建立高層次的理解。
想像一下運行 Kafka 的實體伺服器節點是一間郵局(Kafka Broker),負責收取信件、包裹並轉發派送出去。每天一大早郵局開始營業就會湧入大量的人流(Kafka Producer)想要寄東西,但是他們要寄的東西五花八門,有掛號、快遞、國際件等等,這些人在寄之前自己要知道他們寄件的類別(Topic)。
進到了郵局以後依照類別去往指定的窗口(Partition),一個類別肯定不只有一個窗口對吧,比如要寄掛號的人多,所以有三個窗口都可以辦理,這樣可以有效的分散、消化人流,每個窗口辦理的信件或包裹會貼上一個流水單號(Offset),在後續處理時才不會亂了順序,也不容易搞丟,但是不能跟其他窗口搞混了,每個窗口都要獨立維護次序,跟其他窗口混在一起管理的話,這個流水單號就沒作用了。
把東西交給窗口辦理好後民眾就離開了,這時包裹會在架上等待郵差(Consumer)去領取後派送,每個郵差都只會拿他負責窗口的包裹去遞送,有很多郵差會形成一個小組(Consumer Group)協作分工,他們各自負責指定窗口的任務,不會重複消費,包裹上的流水號也會幫助他們按照順序派送。
Topic 就像 Kafka 訊息的分類容器,Producer 發送訊息要指定 Topic,Consumer 也訂閱 Topic 來接收訊息。每個 Topic 可以有多個 Partition,這可以讓 Kafka 便於水平擴展以及並行處理訊息。
Partition 是 Topic 的物理分片單位,是 Kafka 可以有這麼大吞吐量跟擴展性的基礎。
在一個 Partition 裡又可以分為 leader 跟 follower 兩種不同的角色:
但必須要釐清的是 leader 它本身也是一個分區副本,只不過它是正在服務的那個副本而已,所以嚴格來說,leader & follower 全部加起來才是 Partition 所有副本。
每條 Partition 裡訊息的位置編號,Consumer 會透過 Offset 決定要讀哪一筆訊息。例如 partition-0 上的第 5 筆訊息就等於 offset=4
一個 Kafka Cluster 裡面唯一的老大,郵政總局的概念,被選出來的 Broker 就可以當老大。有新的 Topic 誕生,老大會把 Topic 的 Partition 物理分片均勻分配到各個 Broker 上,就像一種類型的包裹,應該要每家郵局都分散處理,不會說寄快遞只能去台北分行辦理,具體來說就是 Kafka Controller 會考慮:
剛剛在 Partition 的小節中有提到,等一個 Partition 裡的 leader 異常時會從 follower 裡面選出一個新的 leader,這個選舉制度也是由 Kafka Controller 負責的,Controller 會從該 Partition 的 ISR (In-Sync Replica, 同步腳本) 列表中選出一個新 leader,並更新 Metadata 和通知所有 Broker 這個 Partition 的 leader 是誰。(Kafka 會透過內建的 Zookeeper 或新版的 KRaft 模式來維護 Broker 狀態和 Partition 的 Metadata)
注意這邊不是所有的 follower 都有資格在這個列表裡,這裡面的 follower 都是要跟 leader 密切同步的分區副本,它們持續保持落後但不超過某個設定時間的同步狀態。
Consumer Group 簡單來說就是多個 Consumer 組成的群組,由 group id 決定,只要設定相同 group id,無論它們在哪啟動,只要連到同一個 Kafka Cluster 就會被視為同一個 Consumer Group,一個 Partition 一定會被分配到同個 Group 裡的同一個 Consumer,一旦分配到其他的 Consumer 就不能重複消費那個 Partition 的訊息。
不知道這個機制前,我常常會想說本地明明連到 Kafka 為何卻監聽不到消息,原來是因為那個 Topic 就只有一個分區,剛好我比我同事慢了一步連到,他的 Client 端已經先跟那個分區綁定了,之後不管多少訊息都只會由他的 Consumer 來消費,因為我們在同一個 Consumer Group 裡面。
rebalance 是指 Kafka 協調同一個 Consumer Group 裡的所有 Consumer 如何把 Partition 分配給誰的過程。
會做哪些事?
至於什麼時候會觸發 rebalance 呢?
Kafka 是怎麼實作 rebalance 呢?簡單來說是用一個 Group Coordinator 跟 Partition Assignor 的機制來管理的:
注意:rebalance 通常來說是不太好的事,生產環境會想辦法盡可能降低 rebalance 次數,因為這是系統不穩定的來源之一,一旦 rebalance 就代表會造成消費中斷,但它同時也是可伸縮、可容錯的基礎。
今天花了一點時間複習 Kafka 衍生出來的基礎知識,這些基礎知識對於實務上來說非常重要且實用,還是需要反覆精熟,但實際碰到印象還是會比較深刻就是了,所以明天開始就要進入功能的實作了,希望一切順利!