消息队列性能比拼: Kafka vs RabbitMQ

本内容是对知名性能评测博主 Anton Putra Kafka vs RabbitMQ Performance 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。

简介

在本视频中,我们将首先比较 Apache Kafka 和传统的 RabbitMQ 。然后,在第二轮测试中,会将 KafkaRabbitMQ Streams 进行对比,后者在架构和使用场景上更接近 Kafka(RabbitMQ Streams 是一个相对较新的项目,旨在直接与 Kafka 竞争)。

与往常一样,我们将关注 四大核心指标

  1. 吞吐量(Throughput) ---每秒消息数(Messages per second) 衡量。
  2. 延迟(Latency) --- 追踪每条消息的发送和接收所需时间。
  3. 系统负载(Saturation) --- 包括 CPU 使用率 (相对于虚拟机的 CPU 限制)、内存使用情况 ,以及 磁盘操作(因为 Kafka 采用追加式日志,需要将每条消息存储到磁盘)。
  4. 客户端 CPU 负载 --- 统计所有发送和接收消息的客户端的平均 CPU 使用率

为了运行这些测试,我使用了 AWS 。消息代理部署在 i3en.large 规格的实例上,而客户端则运行在 EKS 集群Graviton 实例 上。老实说,这次测试成本不低---要让一个Kafka 代理崩溃,需要消耗大量计算资源。


测试设计

首先,我会快速讲解 KafkaRabbitMQ

Kafka 中,最常用的消息协议之一是 RPC 消息 ,它采用 二进制格式 ,相比 JSON 消息 体积更小。这不仅降低了消息代理的负载,还提高了 延迟吞吐量 指标。此外,你可以在 gRPC服务间通信(Service-to-Service Communication) 中复用这些消息。

在本次测试中,我使用 Device RPC 消息,它包含以下字段:

  • UUID(设备唯一标识符)
  • MAC 地址
  • 固件版本
  • 设备创建的时间戳

你可以在我的 GitHub 公开仓库 中找到源代码。

测试流程

  1. 在生产者端 ,我们使用 随机设备数据 生成 Device RPC 消息,并记录当前时间戳。
  2. 然后,我们 同时 将该消息发送到 Kafka 的TopicRabbitMQ 队列(Queue)
  3. 在消费者端 ,收到消息后,我们从 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

在第二轮测试中,我们对比 KafkaRabbitMQ 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 优化方案 ,欢迎分享,我愿意做 更新测试

相关推荐
Asthenia04126 分钟前
面试复盘:Java String 源码分析与不可变类设计原理
后端
Asthenia04126 分钟前
面试复盘:synchronized 锁与 ReentrantLock 锁的区别及 AQS 认知完善
后端
joker学java42 分钟前
java基础快速入门07
后端
uhakadotcom43 分钟前
了解Pulumi:基础设施即代码的新选择
后端·面试·github
fliter1 小时前
性能比拼: TCP vs UDP(重大改进)
后端
林川的邹1 小时前
如何根据场景判断是使用ArrayList还是LinkedList?
java·后端
Postkarte不想说话1 小时前
ZLMediaKit搭建直播平台
后端
用户86178277365181 小时前
营销邮件
后端
fliter1 小时前
性能比拼: TCP vs UDP(延迟和吞吐量)
后端
Bohemian1 小时前
LeetCode39 组合总和(带扩展)
后端·面试