消息队列性能比拼: Kafka vs RabbitMQ
来源:旅途散记
本内容是对知名性能评测博主 Anton Putra Kafka vs RabbitMQ Performance[1] 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。
简介
我们将首先比较 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 公开仓库[2] 中找到源代码。
测试流程
在生产者端,我们使用 随机设备数据 生成 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 优化方案,欢迎分享,我愿意做 更新测试!
Kafka vs RabbitMQ Performance: https://www.youtube.com/watch?v=UPkOsXKG4ns
[2]GitHub 公开仓库: https://github.com/antonputra/tutorials/tree/main/lessons/218
MySQL要坐不住了!Vitess之父Sugu“投敌”Postgres造新数据库,这次真要掀翻桌子?
为什么DeepSeek火之后,人们想到的是大量裁员,而不是实行上三休四?
苹果“痛下杀手”弃Java,用自家语言Swift重写关键服务:内存减90%,性能增40%!
我的很多DBA朋友,都消失了...
3000亿芯片巨头海光信息拟合并900亿超算龙头中科曙光,国产算力产业的“王炸组合”
1000T的文件怎么能快速从南京传到北京?最佳方案你肯定想不到
麻了,领导让我写个脚本,把700T数据库全部迁移到别的机房,带宽不超过2Mbps
号外!《核心系统分布式数据库选型指南》电子书(附下载)正式上线
解锁数据架构现代化密码,《实时数仓选型指南》电子书(附下载)正式上线啦