圖解Kafka:Kafka架構演化與升級!
了解了 Kafka 架構就掌握了 Kafka 最核心的知識,Kafka 作為業(yè)界最知名、最流行的消息系統(tǒng)和流式處理組件,在面試中和日常工作中經(jīng)常會見到。那么今天,我們就來聊聊 Kafka 的架構演化與升級,并通過圖解的方式讓你一目了然。
1.Kafka 初印象
Kafka 最初由 LinkedIn 公司開發(fā),后來成為了 Apache 軟件基金會的一個開源項目。它的主要設計目標是提供一個高吞吐量、可持久化、分布式的消息系統(tǒng)。
2.Kafka 基礎架構
Kafka 最簡單的基礎架構如下:
圖片
Kafka 主要是由以下 4 部分組成:
- Producer(生產(chǎn)者):消息發(fā)送方,生產(chǎn)者負責創(chuàng)建消息,然后將其投遞到 Kafka(Broker)中。
- Consumer(消費者):接收消息方,消費者連接到 Kafka 上并接收消息,進而進行相應的業(yè)務邏輯處理。
- Broker(代理):一個 Broker 可以簡單地看作一個獨立的 Kafka 服務節(jié)點或 Kafka 服務實例。大多數(shù)情況下也可以將 Broker 看作一臺 Kafka 服務器,前提是這臺服務器上只部署了一個 Kafka 實例。一個或多個 Broker 組成了一個 Kafka 集群。一般而言,我們更習慣使用首字母小寫的 broker 來表示服務代理節(jié)點。
- ZooKeeper:ZooKeeper 是 Kafka(集群)中使用的分布式協(xié)調(diào)服務,用于維護 Kafka(集群)的狀態(tài)和元數(shù)據(jù)信息,例如主題和分區(qū)的分配信息、消費者組和消費者偏移量等信息。
“
Kafka 2.8.0 之后,Kafka 引入了 KRaft(Kafka Raft)模式,它提供了一種新的內(nèi)置的共識機制來替代對 Zookeeper 的依賴。此時,Kafka 可以脫離 Zookeeper 單獨運行,但需要配置 KRaft 控制器才行,Kafka 默認服務還是要配合 Zookeeper 運行的。
3.不同的消息類型怎么辦?
在上述最基礎的 Kafka 架構中我們會發(fā)現(xiàn)一個問題,那就是如果是不同的消息類型要怎么辦?例如以下情況:
圖片
此時,我們可以把不同類型的消息存放在一起,但這樣就需要給消息添加 type 字段,以區(qū)分不同的消息。
但添加了 type 字段之后,后面的維護和擴展又不方便,而且 type 越多,代碼中的判斷代碼就越復雜,想象一下:一個復雜項目的消息類型是有成千上萬個分類的,那我們的判斷代碼也要寫成千上萬個 if-else 判斷不可?這要怎么解決呢?
這時候,我們就需要一個“消息分類機制”,這個機制在 Kafka 里被稱之為 Topic(主題),如下圖所示:
圖片
引入了 Topic 之后,不同的消息就可以發(fā)送到不同的 Topic 了,不同業(yè)務的生產(chǎn)者和消費者就可以實現(xiàn)相互隔離、互不影響了。
“
Broker 和 Topic 的關系:一個 Broker 中可以包含多個 Topic。
4.如何保證高性能?
4.1 數(shù)據(jù)分片
想要提升 Kafka 性能就需要水平擴展 Broker 數(shù)量,如下圖所示:
圖片
在 Kafka 中,Topic 是用 Partition(分區(qū))存儲的,所以它正確的交互流程如下所示:
圖片
這小節(jié)核心知識點:
- Partition(分區(qū))就是真正存儲數(shù)據(jù)的消息隊列。
- 有了集群和多個 Partition 之后,Kafka 的數(shù)據(jù)就可以實現(xiàn)分片存儲了,性能也得到很大的提升。
什么是數(shù)據(jù)分片?
數(shù)據(jù)分片存儲是一種將大量數(shù)據(jù)分散存儲在多個不同位置或設備上的技術。
在數(shù)據(jù)量龐大的情況下,為了提高數(shù)據(jù)的存儲效率、訪問性能和可擴展性,將數(shù)據(jù)分割成較小的片段,然后分別存儲在不同的節(jié)點或存儲設備中。
以下是一些數(shù)據(jù)分片存儲的特點和優(yōu)勢:
- 提高性能:通過將數(shù)據(jù)分散存儲,可以并行地處理數(shù)據(jù)請求,從而加快數(shù)據(jù)的讀取和寫入速度。例如,在一個分布式數(shù)據(jù)庫中,不同的分片可以同時響應查詢,減少了總體的響應時間。
- 增強可擴展性:當數(shù)據(jù)量不斷增長時,可以方便地添加更多的分片來擴展存儲容量,而無需對整個系統(tǒng)進行大規(guī)模的重構。
- 避免單點性能瓶頸:數(shù)據(jù)分片可以使數(shù)據(jù)的存儲和訪問負載更加均衡地分布在多個節(jié)點上,避免單個節(jié)點成為性能瓶頸。
4.2 消費組
如果沒有消費組,那么一個 Topic 只能被一個消費者消費,性能會很低,如下圖所示:
圖片
消費組(Consumer Group)是一個由多個消費者(Consumer)組成的邏輯概念,用于實現(xiàn)對一個主題(Topic)中消息進行并發(fā)消費和負載均衡的機制。
圖片
特性分析
Kafka 消費組特性如下:
- 并發(fā)執(zhí)行:將一個主題內(nèi)的消息分給多個消費者并發(fā)處理,提升了消息消費的性能。
- 容錯性好:如果組內(nèi)的某個消費者發(fā)生故障,Kafka 能夠自動地將該消費者負責的分區(qū)重新分配給其他健康的消費者,確保消息不會被遺漏。
- 支持多種消費模式:通過調(diào)整消費者組的配置,可以實現(xiàn)不同的消費模式,如發(fā)布訂閱模式(一對多)和隊列模式(一對一)。在發(fā)布訂閱模式下,一個消息可以被多個消費者組同時消費,每個消費者組內(nèi)的消費者則共享該消息;在隊列模式下,一個消息只能被一個消費者組內(nèi)的某個消費者消費。這種靈活性使得Kafka可以適應不同的業(yè)務需求和數(shù)據(jù)處理場景。
- 動態(tài)擴展:隨著業(yè)務規(guī)模的擴大或縮小,可以動態(tài)地增加或減少消費者組的成員。新加入的消費者會自動從已有的副本中拉取數(shù)據(jù)并開始消費;而離開的消費者會自動感知并停止消費。這種動態(tài)的擴展性使得 Kafka 能夠隨著業(yè)務的發(fā)展而靈活地擴展處理能力。
“
消費組和分區(qū)的關系:消費者(數(shù)量) <= 分區(qū)數(shù)。
5.如何保證高可用?
圖片
Partition 備份節(jié)點叫做 Follower 節(jié)點,負責數(shù)據(jù)讀寫的節(jié)點叫做 Leader 節(jié)點。
Kafka 分區(qū)類型有以下兩種:
- Leader Partition:主節(jié)點,負責數(shù)據(jù)寫入和讀取。
- Follower Partition:副本節(jié)點,用于數(shù)據(jù)備份和主節(jié)點宕機之后的分區(qū)選舉,保證了 Kafka 服務的高可用。
小結
Kafka 架構最終組成如下:
圖片
它們分別是:
- 生產(chǎn)者(Producer):負責將消息發(fā)送到 Kafka 集群。
- 消費組(Consumer Group):用于實現(xiàn)對一個主題(Topic)中消息進行并發(fā)消費和負載均衡的機制。
- 消費者(Consumer):負責從 Kafka 集群中讀取、消費消息。
- 代理(Broker):Kafka 服務器(Kafka 服務),負責存儲和轉發(fā)消息。
- 主題(Topic):消息的邏輯分類,生產(chǎn)者將消息發(fā)送到特定的主題,消費者從特定的主題訂閱消息。
- 分區(qū)(Partition):主題可以被分為多個分區(qū),每個分區(qū)是一個有序的、不可變的消息序列。分區(qū)可以分布在不同的 broker 上,實現(xiàn)水平擴展。分區(qū)分為 Leader 分區(qū),和 Follower 分區(qū)。
- Zookeeper:用于管理 Broker 集群的元數(shù)據(jù),如分區(qū)分配、領導者選舉、消費者組和消費者偏移量等信息等。