作為一名有著大量微服務(wù)系統(tǒng)處理經(jīng)驗(yàn)的軟件架構(gòu)師,我經(jīng)常遇到一個(gè)不斷重復(fù)的問題:“我應(yīng)該使用 RabbitMQ 還是 Kafka?”出于某種原因,許多開發(fā)人員認(rèn)為這些技術(shù)是可以互換的。雖然在某些情況下確實(shí)如此,但 RabbitMQ 還是 Kafka 之間存在根本上的差異。
因此,不同的場(chǎng)景需要不同的解決方案,選擇錯(cuò)誤的方案會(huì)嚴(yán)重影響我們的軟件開發(fā)設(shè)計(jì)以及后續(xù)維護(hù)軟件。
本文的目標(biāo)首先是介紹基本的異步消息傳遞模式。然后繼續(xù)介紹 RabbitMQ 和 Kafka 及其內(nèi)部結(jié)構(gòu)。第 2 部分重點(diǎn)介紹了這些平臺(tái)之間的關(guān)鍵區(qū)別、它們的各種優(yōu)點(diǎn)和缺點(diǎn),以及如何在兩者之間進(jìn)行選擇。
異步消息傳遞是一種消息傳遞方案,其中生產(chǎn)者的消息生成與消費(fèi)者的消息處理分離。在消息傳遞系統(tǒng)中,我們通常會(huì)分為兩種主要的消息傳遞模式:隊(duì)列模式和發(fā)布/訂閱模式。
在隊(duì)列模式中,隊(duì)列暫時(shí)將生產(chǎn)者與消費(fèi)者解耦。多個(gè)生產(chǎn)者可以向同一個(gè)隊(duì)列發(fā)送消息。然后當(dāng)消費(fèi)者處理消息時(shí),消息會(huì)被鎖定然后從隊(duì)列中刪除,并且不再可用。
隊(duì)列模式通常就是一個(gè)消息只能被一個(gè)消費(fèi)者處理。
消息隊(duì)列
附帶說明一下,如果消費(fèi)者無法處理某個(gè)消息,消息平臺(tái)通常會(huì)將消息返回到隊(duì)列,以供其他消費(fèi)者使用。除了解耦之外,隊(duì)列還允許我們擴(kuò)展生產(chǎn)者和消費(fèi)者,并針對(duì)錯(cuò)誤處理提供容錯(cuò)能力。
在發(fā)布/訂閱模式中,單個(gè)消息可以由多個(gè)訂閱者同時(shí)接收和處理。
發(fā)布/訂閱
例如,此模式允許發(fā)布者通知所有訂閱者系統(tǒng)中發(fā)生了某些情況。在 RabbitMQ 中,主題是一種特定類型的 pub/sub 實(shí)現(xiàn)(確切地說是一種交換類型),但在本文中,我將主題稱為整個(gè) pub/sub 的表示。
一般來說,訂閱有兩種類型:
RabbitMQ 是消息代理的一種實(shí)現(xiàn) — 通常稱為服務(wù)總線。它本身支持上述兩種消息傳遞模式。消息代理的其他流行實(shí)現(xiàn)包括 ActiveMQ、ZeroMQ、Azure 服務(wù)總線和 Amazon Simple Queue Service (SQS)。所有這些實(shí)現(xiàn)都有很多共同點(diǎn),本文中描述的許多概念適用于其中的大多數(shù)。
RabbitMQ 支持開箱即用的經(jīng)典消息隊(duì)列。開發(fā)人員定義命名隊(duì)列,然后發(fā)布者可以將消息發(fā)送到該命名隊(duì)列。反過來,消費(fèi)者使用相同的隊(duì)列來檢索消息來處理它們。
RabbitMQ 通過使用消息交換機(jī)來實(shí)現(xiàn) pub/sub。發(fā)布者將其消息發(fā)布到消息交換機(jī),不用知道這些消息的訂閱者是誰。
每個(gè)訂閱交換機(jī)的消費(fèi)者都會(huì)創(chuàng)建一個(gè)隊(duì)列,然后消息交換機(jī)將生成的消息排隊(duì)以供消費(fèi)者使用。它還可以根據(jù)各種路由規(guī)則過濾某些訂閱者的消息。
RabbitMQ message exchange
值得注意的是,RabbitMQ 支持臨時(shí)訂閱和持久訂閱。消費(fèi)者可以通過 RabbitMQ 的 API 決定他們想要使用的訂閱類型。
由于 RabbitMQ 的架構(gòu),我們還可以創(chuàng)建一種混合方法,其中一些訂閱者形成消費(fèi)者組,這些消費(fèi)者組以特定隊(duì)列上競(jìng)爭(zhēng)消費(fèi)者的形式共同處理消息。通過這種方式,我們實(shí)現(xiàn)了發(fā)布/訂閱模式,同時(shí)還允許一些訂閱者擴(kuò)展以處理接收到的消息。
發(fā)布/訂閱和隊(duì)列相結(jié)合
Apache Kafka 是一個(gè)分布式流處理平臺(tái)。
與基于隊(duì)列和交換的 RabbitMQ 不同,Kafka 的存儲(chǔ)層是使用分區(qū)事務(wù)日志實(shí)現(xiàn)的。Kafka 還提供了 Streams API 來實(shí)時(shí)處理流,以及 Connectors API 來輕松與各種數(shù)據(jù)源集成。不過,這些超出了本文的范圍。
云服務(wù)商為 Kafka 的存儲(chǔ)層提供了替代解決方案。這些解決方案包括 Azure 事件中心,在某種程度上還包括 AWS Kinesis Data Streams。Kafka 的流處理功能還有特定于云的開源替代方案,同樣,這些也超出了本文的范圍。
Kafka 沒有實(shí)現(xiàn)隊(duì)列的概念。Kafka 將記錄集合存儲(chǔ)在稱為主題的類別中。
對(duì)于每個(gè)主題,Kafka 都會(huì)維護(hù)一個(gè)分區(qū)的消息日志。每個(gè)分區(qū)都是一個(gè)有序的、不可變的記錄序列,其中不斷附加消息。
Kafka 在消息到達(dá)時(shí)將其附加到這些分區(qū)。默認(rèn)情況下,它使用循環(huán)分區(qū)器在分區(qū)之間均勻地傳播消息。
生產(chǎn)者可以修改此行為以創(chuàng)建邏輯消息流。例如在多租戶應(yīng)用程序中,我們可能希望根據(jù)每條消息的租戶 ID 創(chuàng)建邏輯消息流。在物聯(lián)網(wǎng)場(chǎng)景中,我們可能希望將每個(gè)生產(chǎn)者的身份不斷映射到特定分區(qū)。確保來自同一邏輯流的所有消息映射到同一分區(qū),以保證它們按順序傳遞給消費(fèi)者。
Kafka producers
消費(fèi)者通過維護(hù)這些分區(qū)的偏移量(或索引)并按順序讀取它們來消費(fèi)消息。
單個(gè)消費(fèi)者可以使用多個(gè)主題,并且消費(fèi)者可以擴(kuò)展,直至與可用分區(qū)數(shù)量一致。
因此,在創(chuàng)建主題時(shí),應(yīng)仔細(xì)考慮該主題的消息傳遞的預(yù)期吞吐量。共同消費(fèi)某個(gè)主題的一組消費(fèi)者稱為消費(fèi)者組。Kafka 的 API 通常負(fù)責(zé)消費(fèi)者組中消費(fèi)者之間分區(qū)處理的平衡以及消費(fèi)者當(dāng)前分區(qū)偏移量的存儲(chǔ)。
Kafka consumers
Kafka 的內(nèi)部實(shí)現(xiàn)其實(shí)很好地反映了 pub/sub 模式。
生產(chǎn)者可以向特定主題發(fā)送消息,多個(gè)消費(fèi)者組可以消費(fèi)同一條消息。每個(gè)消費(fèi)者組都可以單獨(dú)擴(kuò)展以處理負(fù)載。由于消費(fèi)者維護(hù)其分區(qū)偏移量,因此他們可以選擇持久訂閱(在重新啟動(dòng)時(shí)維持其偏移量)或臨時(shí)訂閱(即丟棄偏移量并在每次啟動(dòng)時(shí)從每個(gè)分區(qū)中的最新記錄重新啟動(dòng))。
Kafka 其實(shí)是不太適合隊(duì)列模式的消息傳遞。當(dāng)然我們可以創(chuàng)建一個(gè)只有一個(gè)消費(fèi)者組的主題來模擬經(jīng)典的消息隊(duì)列。但這有多個(gè)缺點(diǎn),在本文第 2 部分我們將詳細(xì)討論。
第 2 部分文章地址:https://betterprogramming.pub/rabbitmq-vs-kafka-1779b5b70c41
值得注意的是,無論消費(fèi)者是否消費(fèi)了這些消息,Kafka 都會(huì)將消息保留在分區(qū)中直至預(yù)先配置的時(shí)間段內(nèi)。這種保留意味著消費(fèi)者可以自由地重讀過去的消息。此外,開發(fā)人員還可以使用 Kafka 的存儲(chǔ)層來實(shí)現(xiàn)事件溯源和審計(jì)日志等機(jī)制。
雖然 RabbitMQ 和 Kafka 有時(shí)可以互換,但它們的實(shí)現(xiàn)卻截然不同。因此,我們不能將它們視為同一類別工具的成員。一個(gè)是消息代理,另一個(gè)是分布式流平臺(tái)。
作為解決方案架構(gòu)師,我們應(yīng)該認(rèn)識(shí)到這些差異,并積極考慮針對(duì)給定場(chǎng)景應(yīng)使用哪些類型的解決方案。
本文鏈接:http://www.www897cc.com/showinfo-26-68337-0.htmlRabbitMQ vs Kafka,我到底該如何選?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com