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