本內容是對知名性能評測博主 Anton Putra Kafka vs RabbitMQ Performance 內容的翻譯與整理, 有適當刪減, 相關數據和結論以原作結論為準。
簡介
在本視頻中,我們將首先比較 Apache Kafka 和傳統的 RabbitMQ。然后,在第二輪測試中,會將 Kafka 與 RabbitMQ Streams 進行對比,后者在架構和使用場景上更接近 Kafka(RabbitMQ Streams 是一個相對較新的項目,旨在直接與 Kafka 競爭)。
與往常一樣,我們將關注 四大核心指標:
- 吞吐量(Throughput)
---
以 每秒消息數(Messages per second) 衡量。 - 延遲(Latency)
---
追蹤每條消息的發送和接收所需時間。 - 系統負載(Saturation)
---
包括 CPU 使用率(相對于虛擬機的 CPU 限制)、內存使用情況,以及 磁盤操作(因為 Kafka 采用追加式日志,需要將每條消息存儲到磁盤)。 - 客戶端 CPU 負載
---
統計所有發送和接收消息的客戶端的平均 CPU 使用率。
為了運行這些測試,我使用了 AWS。消息代理部署在 i3en.large 規格的實例上,而客戶端則運行在 EKS 集群 的 Graviton 實例 上。老實說,這次測試成本不低---
要讓一個Kafka 代理崩潰,需要消耗大量計算資源。
測試設計
首先,我會快速講解 Kafka 和 RabbitMQ。
在 Kafka 中,最常用的消息協議之一是 RPC 消息,它采用 二進制格式,相比 JSON 消息 體積更小。這不僅降低了消息代理的負載,還提高了 延遲 和 吞吐量指標。此外,你可以在 gRPC 和 服務間通信(Service-to-Service Communication) 中復用這些消息。
在本次測試中,我使用 Device RPC 消息,它包含以下字段:
- UUID(設備唯一標識符)
- MAC 地址
- 固件版本
- 設備創建的時間戳
你可以在我的 GitHub 公開倉庫 中找到源代碼。
測試流程
- 在生產者端,我們使用 隨機設備數據 生成 Device RPC 消息,并記錄當前時間戳。
- 然后,我們 同時 將該消息發送到 Kafka 的Topic 和 RabbitMQ 隊列(Queue)。
- 在消費者端,收到消息后,我們從
created_at
字段中提取時間戳,并計算 消息延遲。
注意:我們不依賴 Kafka 或 RabbitMQ 內部指標 來測量延遲,而是直接在 客戶端 端測量,這樣測試方式對兩者是 公平且準確 的。
如果你認為 測試設計 或 客戶端源碼 可以優化,歡迎提出建議或提交 Pull Request!
第一輪測試:Kafka vs. 傳統 RabbitMQ
讓我們開始第一輪測試,比較 Kafka 和 傳統 RabbitMQ(后者主要將消息存儲在 內存 中)。
剛開始,你就會注意到:
-
RabbitMQ 的消息發送和接收延遲比 Kafka 低近一半。這對于某些應用場景可能至關重要,也可能無關緊要,但總體來說,RabbitMQ 的延遲更低。
-
右側圖表 顯示了每個消息系統每秒 處理的消息數。
-
Kafka 的 CPU 使用率更高,因為它必須將 每一條消息寫入磁盤。
-
左側圖表 顯示 Kafka 正在 頻繁進行磁盤寫入,而 RabbitMQ 幾乎不訪問磁盤(甚至完全不觸碰磁盤)。
另一個重要點:Kafka 的 生產者 和 消費者 的 CPU 使用率 約為 RabbitMQ 客戶端的兩倍。
當 Kafka 的 CPU 使用率達到 50% 時,延遲開始顯著上升。也就是說,當 Kafka 的 CPU 超過 50% 時,其延遲會開始惡化,如果你對低延遲有嚴格要求,這一點需要特別注意。
RabbitMQ 的極限
- 當 RabbitMQ 處理達到 15,000 條消息/秒 時,CPU使用率達到 100% ,開始 崩潰,延遲急劇上升。
- 當 RabbitMQ 處理達到 33,000 條消息/秒 時,生產者和消費者 超時(默認超時 5 秒),開始 請求失敗。這意味著 RabbitMQ 的最大吞吐量約為 33,000 條消息/秒。
Kafka 的極限
-
Kafka 的 CPU 在更早的階段就達到了 100%,但它 仍然能夠繼續處理 所有消息。盡管 延遲增加,但 Kafka 仍 持續運作。
-
繼續推高負載,我們發現 Kafka 在 230,000 條消息/秒 時達到極限。
接下來,我們打開每個圖表,分析整個測試過程的數據。
數據分析
第一輪測試(Kafka vs. RabbitMQ):
- 吞吐量:Kafka 遠超 RabbitMQ。
- 延遲:RabbitMQ 低得多,這也是 選擇 RabbitMQ 的主要原因。
- 磁盤操作:(本次測試)Kafka 依賴 本地 SSD,提高了性能。
- CPU 使用率:雖然Kafka使用了更多的CPU,但 即使達到 100% CPU 仍能持續運行,而不會像 RabbitMQ 那樣CPU到達100%很快失敗(因為RabbitMQ主要將數據存儲在內存中?)。
- 客戶端的CPU使用情況:
- 內存使用:RabbitMQ CPU 100% 時,內存使用發生尖峰。
第二輪測試:Kafka vs. RabbitMQ Streams
在第二輪測試中,我們對比 Kafka 和 RabbitMQ Streams。
- 一開始,RabbitMQ Streams 的延遲就明顯更高。
- 我使用了 官方 Golang 庫,它采用 RabbitMQ Streams 專用的二進制協議。
- 這次,RabbitMQ 從一開始就開始寫入磁盤,但其 CPU 使用率在測試初期遠低于 Kafka。
RabbitMQ Streams 的極限
-
Kafka 在 12,000 條消息/秒 時 CPU 達到 100% ,延遲開始上升。
-
RabbitMQ 的 CPU 此時只有 15% ,我推測這是因為 RabbitMQ 處理每條消息的延遲較高。
-
當 RabbitMQ 處理達到 100,000 條消息/秒 時,CPU 100% ,并且性能進一步下降。
- 當 RabbitMQ 處理達到 135,000 條消息/秒 時,徹底失敗。
Kafka 的極限
- 我繼續增加 Kafka 的負載,最終 Kafka 在 272,000 條消息/秒 時崩潰。
接下來,我們打開所有圖表,逐項分析數據。
數據分析
第二輪測試(Kafka vs. RabbitMQ Streams):
- RabbitMQ Streams 的吞吐量(和第一次測試所用的RabbitMQ相比)有所提升,但 整體速度比 Kafka 慢。
- RabbitMQ Streams 的延遲極高,只適用于 批量數據處理或非延遲敏感的場景,不適用于 低延遲應用。
- 每秒磁盤寫入操作的次數:
- CPU使用情況:
- 客戶端的平均CPU使用情況:
- 內存使用情況:
結論
- 如果你需要低延遲,并且 RabbitMQ 滿足你的需求,那就選 RabbitMQ。
- 如果你需要高吞吐量、穩定性和可擴展性,Kafka 是更好的選擇。
- 在第二輪測試中,Kafka 明顯勝出。
如果你有更好的 RabbitMQ Streams 優化方案,歡迎分享,我愿意做 更新測試!