kafka VS Rabbit

1. 前言

經歷過多個基於微服務的場景,經常在問自己“到底是用Kafka還是Rabbit,二者之間該怎麼選擇,它們各有什麼優點和缺點”。本文先從他們內部的消息傳遞模式說起。

2. 架構對比

2.1. Rabbitmq

RabbitMQ架構
RabbitMQ是一個通用的消息代理,通過包括點對點、請求/響應及發佈訂閱在內的多種消息通信模式。其採用的是一種智能代理/傻瓜消費的模式,側重消息的持續投遞與處理,並通過代理本身來維護消費者自身狀態。RabbitMQ是一個設計成熟的消息代理中間件,支持包括Java, node.js, .NET, Ruby, PHP等在內的多種客戶端,並且提供有多種插件來擴展自身功能。

RabbitMQ支持異步或者同步消息通信,生產者將消息發送到交換器中,消費者則從消息隊列中獲取消息。交換器將生產者從消息隊列中解耦,避免了實際運用中消息路由的硬編碼問題。RabbitMQ同時支持分佈式部署,多個服務節點可以在完全不依賴外部其他服務(一些集羣服務插件,比如:AWS APIs,DNS, Consul等等除外)的前提下組成一個服務集羣。

2.2. Kafka

Kakka架構圖
Kakfa是一個高吞吐量的發佈訂閱消息系統和流處理平臺,類似於服務器集羣中的日誌系統,Kafka以主題的形式爲消息流提供了持久消息存儲。

Kafka中的每一個消息都包含一個鍵、值以及時間戳,與RabbitMQ相反,Kafka採用的是一種傻瓜代理/智能消費的模式,Kakfa只記錄未讀消息,相應的Kafka採取的是爲所有的消息保留一定的時間窗口,同時,消費者負責各自記錄自身讀取消息的實際位置(.log)。因此,通過適合的客戶端代碼,Kafka可以以非常小的代價支持大量的消費者和數據。如圖所示,Kafka本身需要藉助外部服務(比如ZooKeeper)來實現相應功能。

3. 需求場景

3.1. Kafka 適合場景

Kafka本身包含消息代理,這也是其最爲顯出和最受歡迎的部分,因此也常用於流式處理。除此之外,Kafka最近也引入了Kafka Streams,作爲與Spark、Flink、Beam、Google Cloud Data Flow和Spring Cloud Data Flow類似的流平臺備選方案。Kafka的主要應用場景包含:網站行爲跟蹤、度量,日誌聚合、流式處理、事件溯源及提交日誌等等,其中,消息路由是應用場景之一,其中,以下消息路由場景最適宜Kafka:

  • 從A到B的流不需要複雜的路由,最大吞吐量(100k/sec+),至少包含一次按分區順序路由。
  • 當應用需要訪問流歷史,至少包含一次按分區順序路由。與其他傳統的消息中間件(消息一旦路由,即會被從消息隊列中刪除)不同,Kafka提供持久消息存儲,客戶端根據需要進行事件回溯。
  • 流式處理
  • 事件溯源

3.2. RabbitMQ 適合場景

RabbitMQ提供的是通用的消息路由解決方案,通常用於服務器的快速響應。還可以用於路由消息給多個消費者或者實現高負載(20k+/s)下的負載均衡。RabbitMQ最適用於以下場景:

  • 應用包含多種協議:AMQP 0-9-1, STOMP, MQTT, AMQP 1.0.
  • 應用需要確保單個消息級別粒度的一致性控制/路由保證(Kafka已新增事務支持)
  • 應用需要多種消息路由方式:點對點、請求/響應、發佈訂閱
  • 包含多個服務與應用的路由交互,且路由邏輯複雜。

4. 性能對比

  • Kafka性能卓越,最高可達100k/s,這也是促使很多人選擇kafka的重要原因所在。當然了,每秒處理消息的速率是很難表述和量化的,因爲在很大程度上,這個指標都依賴於實際環境和硬件設施。
  • 在不考慮可靠性的前提下,通過單個Rabbit隊列達到20K/s的處理效率也並非難事,但RabbitMQ內部消息隊列是基於Erlang實現的輕量級線程支持,由本地操作系統上的線程池協同調度,因而,RabbitMQ的性能瓶頸在於CPU的時鐘週期的獲取。

5. 消息傳遞模式對比

5.1. 異步消息傳遞模式

異步消息傳遞是一種消息傳遞方案,其中生產者的消息生產與消費者的消息處理不相關。 在處理消息傳遞系統時,我們通常會確定兩種主要的消息傳遞模式-消息排隊和發佈/訂閱。

5.1.1. 消息隊列

隊列在時間上使生產者與消費者脫鉤。 多個生產者可以將消息發送到同一隊列。 但是,當使用者處理消息時,該消息將被鎖定或從隊列中刪除,並且不再可用。 只有一個消費者消費一條特定的消息。如果使用者無法處理某條消息,則消息傳遞平臺通常會將消息返回到隊列中,以供其他使用者使用。 除了臨時解耦,隊列還使我們能夠獨立地擴展生產者和消費者的規模,並提供一定程度的容錯能力以應對處理錯誤。

消息隊列模型

5.1.2. 發佈/訂閱

在發佈/訂閱(或pub / sub)通信模式中,多個訂戶可以同時接收和處理一條消息。單個消息可以被多個訂閱者併發的獲取和處理。
發佈訂閱

一個系統中產生的事件可以通過這種模式讓發佈者通知所有訂閱者。在許多隊列系統中常常用主題(topics)這個術語指代發佈/訂閱模式。
在 RabbitMQ 中,主題就是發佈/訂閱模式的一種具體實現(更準確點說是交換(exchange)的一種),但是在這篇文章中,我會把主題和發佈/訂閱當做等價來看待。一般來說,訂閱有兩種類型:

  • 臨時(ephemeral)訂閱,這種訂閱只有在消費者啓動並且運行的時候才存在。一旦消費者退出,相應的訂閱以及尚未處理的消息就會丟失。
  • 持久(durable)訂閱,這種訂閱會一直存在,除非主動去刪除。消費者退出後,消息系統會繼續維護該訂閱,並且後續消息可以被繼續處理。

5.2. RabbitMQ

RabbitMQ 作爲消息中間件的一種實現,常常被當作一種服務總線來使用。RabbitMQ 原生就支持上面提到的兩種消息模式。其他一些流行的消息中間件的實現有 ActiveMQ,ZeroMQ,Azure Service Bus 以及 Amazon Simple Queue Service(SQS)。

5.2.1. RabbitMQ消息隊列

RabbitMQ 支持典型的開箱即用的消息隊列。開發者可以定義一個命名隊列,然後發佈者可以向這個命名隊列中發送消息。最後消費者可以通過這個命名隊列獲取待處理的消息。

5.2.2. RabbitMQ消息交換器

RabbitMQ 使用消息交換器(exchange)來實現發佈/訂閱模式。發佈者可以把消息發佈到消息交換器上而不用知道這些消息都有哪些訂閱者。每一個訂閱了交換器的消費者都會創建一個隊列;然後消息交換器會把生產的消息放入隊列以供消費者消費。消息交換器也可以基於各種路由規則爲一些訂閱者過濾消息。
RabbitMQ消息交換器
RabbitMQ支持臨時訂閱和持久訂閱。 消費者可以通過RabbitMQ的API決定要使用的訂閱類型。
根據 RabbitMQ 的架構設計,我們也可以創建一種混合方法——訂閱者以組隊的方式然後在組內以競爭關係作爲消費者去處理某個具體隊列上的消息,這種由訂閱者構成的組我們稱爲消費者組。按照這種方式,我們實現了發佈/訂閱模式,同時也能夠很好的伸縮(scale-up)訂閱者去處理收到的消息。

發佈訂閱隊列混合使用

5.3. Kafka

Apache Kafka 不是消息中間件的一種實現。相反,它只是一種分佈式流式系統。不同於基於隊列和交換器的 RabbitMQ,Kafka 的存儲層是使用分區事務日誌來實現的。

5.3.1. 消息主題Topic

Kafka 沒有實現隊列這種東西。相應的,Kafka 按照類別存儲記錄集,並且把這種類別稱爲主題。Kafka 爲每個主題維護一個消息分區日誌。每個分區都是由有序的不可變的記錄序列組成,並且消息都是連續的被追加在尾部。當消息到達時,Kafka 就會把他們追加到分區尾部。默認情況下,Kafka 使用輪詢分區器(partitioner)把消息一致的分配到多個分區上。

Kafka生產者可以改變創建消息邏輯流的行爲。例如,在一個多租戶的應用中,我們可以根據每個消息中的租戶 ID 創建消息流。確保來自相同邏輯流上的消息映射到相同分區上,這就保證了消息能夠按照順序提供給消費者。
kafka生產者
消費者通過維護分區的偏移(或者說索引)來順序的讀出消息,然後消費消息。單個消費者可以消費多個不同的主題,並且消費者的數量可以伸縮到可獲取的最大分區數量。所以在創建主題的時候,我們要認真的考慮一下在創建的主題上預期的消息吞吐量。

消費同一個主題的多個消費者構成的組稱爲消費者組。通過 Kafka 提供的 API 可以處理同一消費者組中多個消費者之間的分區平衡以及消費者當前分區偏移的存儲。

消費者消費者羣組

5.3.2. Kafka 實現的消息模式

  • Kafka 的實現很好地契合發佈/訂閱模式。生產者可以向一個具體的主題發送消息,然後多個消費者組可以消費相同的消息。每一個消費者組都可以獨立的伸縮去處理相應的負載。

  • 由於消費者(消費者組)維護自己的分區偏移,所以他們可以選擇持久訂閱或者臨時訂閱,持久訂閱在重啓之後不會丟失偏移而臨時訂閱在重啓之後會丟失偏移並且每次重啓之後都會從分區中最新的記錄開始讀取。但是這種實現方案不能完全等價的當做典型的消息隊列模式看待。當然,我們可以創建一個主題,這個主題和擁有一個消費者的消費組進行關聯。

  • Kafka 是按照預先配置好的時間保留分區中的消息,而不是根據消費者是否消費了這些消息。這種保留機制可以讓消費者自由的重讀之前的消息。另外,開發者也可以利用Kafka的存儲層來實現諸如事件溯源和日誌審計功能。

6. 參考文獻

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章