news 2026/2/4 19:30:33

【MQ】Kafka与RocketMQ深度对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【MQ】Kafka与RocketMQ深度对比

Kafka与RocketMQ深度对比

前言

很多人问:Kafka 和 RocketMQ 到底该选哪个?这篇文章我们就来深入对比一下这两个消息队列的架构差异、功能特性和性能表现,帮你做出更好的技术选型。

🏠个人主页:你的主页


文章目录

  • Kafka与RocketMQ深度对比
    • 一、一句话总结两者差异
    • 二、架构上做减法
    • 三、存储模型的差异
    • 四、主从同步机制对比
    • 五、功能上做加法
    • 六、性能差异的根本原因
    • 七、如何选型
    • 八、总结

一、一句话总结两者差异

RocketMQ 是在架构上做减法,在功能上做加法

什么意思呢?

  • 架构做减法:简化了 Kafka 的一些设计,让系统更轻量
  • 功能做加法:增加了很多 Kafka 没有的实用功能

但代价是什么?性能。Kafka 每秒能处理 17 万级别的数据,RocketMQ 是 10 万级别。不是 RocketMQ 弱,而是 Kafka 性能太强了。


二、架构上做减法

2.1 用 NameServer 替换 Zookeeper

Kafka 早期依赖 Zookeeper 来管理集群元数据。但 Zookeeper 是一个重量级的分布式协调服务,它能干的事情太多了:

  • 服务注册与发现
  • 分布式锁
  • 配置管理
  • Leader 选举

而 Kafka 只用到了其中一小部分功能,这就好比你只想切个苹果,却搬来一整套厨房设备。

RocketMQ 的做法是:既然用不到那么多功能,那就换一个更轻量的组件——NameServer

打个比方

  • Zookeeper 像一个功能齐全的智能家居中控系统,能控制灯光、空调、窗帘、安防…
  • NameServer 像一个简单的通讯录,只负责告诉你"某个服务在哪台机器上"

NameServer 的特点:

特性说明
无状态每个 NameServer 节点相互独立,不需要同步数据
轻量代码量少,部署简单
高可用挂掉一个不影响其他节点

不过值得一提的是,Kafka 从2.8.0 版本开始也在逐步移除 Zookeeper 依赖,引入了 KRaft 模式。看来大家都意识到 Zookeeper 太重了。

2.2 简化分区模型

Kafka 把 Topic 拆分成多个Partition(分区)来提升并发能力,RocketMQ 也一样,只不过换了个名字叫Queue(队列)。

但两者的存储方式完全不同:

Kafka 的方式

Topic ├── Partition-0 → 存储完整消息 ├── Partition-1 → 存储完整消息 └── Partition-2 → 存储完整消息

每个 Partition 是一个独立的日志文件,消息直接写在里面。

RocketMQ 的方式

Broker ├── CommitLog → 存储所有消息的完整数据(顺序写入) ├── Queue-0 → 只存储 offset(指向 CommitLog 的位置) ├── Queue-1 → 只存储 offset └── Queue-2 → 只存储 offset

Queue 里只存简要信息(主要是 offset),真正的消息数据都在CommitLog里。

打个比方

  • Kafka 像是每个部门都有自己的档案柜,文件直接放在各自的柜子里
  • RocketMQ 像是公司有一个统一的档案室(CommitLog),各部门只保留一个索引本(Queue),记录"我的文件在档案室的第几页"

三、存储模型的差异

3.1 读取性能对比

因为存储方式不同,读取消息的过程也不一样:

Kafka 读取消息

1. 找到对应的 Partition 2. 直接读取消息 ✅ 一次搞定

RocketMQ 读取消息

1. 从 Queue 读取 offset 2. 根据 offset 去 CommitLog 读取完整消息

RocketMQ 需要两次读取,看起来效率更低?别急,继续往下看。

3.2 写入性能对比

这里就是 RocketMQ 设计的精妙之处了。

Kafka 的写入问题

假设一个 Broker 上有 100 个 Topic,每个 Topic 有 10 个 Partition,那就是 1000 个 Partition。每个 Partition 对应磁盘上不同位置的文件。

写消息到 Topic-A-Partition-0 → 磁盘位置 A 写消息到 Topic-B-Partition-3 → 磁盘位置 B 写消息到 Topic-C-Partition-7 → 磁盘位置 C

虽然单个 Partition 内是顺序写,但多个 Partition 分布在磁盘不同位置,整体上就变成了随机写

打个比方:你要往 10 本不同的笔记本上写字,每写一行就要换一本,手忙脚乱。

RocketMQ 的解决方案

所有消息不管属于哪个 Topic,统统写到同一个 CommitLog 文件里。

消息1(Topic-A)→ CommitLog 消息2(Topic-B)→ CommitLog 消息3(Topic-C)→ CommitLog

这样就把随机写变成了顺序写,磁盘 IO 效率大大提升。

打个比方:不管什么内容,都往同一本笔记本上写,写完一页翻下一页,行云流水。

结论:在多 Topic 场景下,RocketMQ 的写入性能优于 Kafka。


四、主从同步机制对比

数据可靠性需要主从备份,两者的同步方式也不同。

Kafka 的主从同步

Broker-1 (Leader) ├── Partition-0 ──同步──→ Broker-2 (Follower) Partition-0 ├── Partition-1 ──同步──→ Broker-3 (Follower) Partition-1 └── Partition-2 ──同步──→ Broker-2 (Follower) Partition-2

以 Partition 为单位同步,每个 Partition 单独建立同步通道。

RocketMQ 的主从同步

如果还像 Kafka 一样按分区同步,就得把 CommitLog 里的内容拆开,又退化成随机读写了。

所以 RocketMQ 索性直接同步整个 CommitLog 文件

Master Broker └── CommitLog ──整体同步──→ Slave Broker CommitLog

以 Broker 为单位区分主从,大大简化了备份模型。


五、功能上做加法

RocketMQ 在功能上比 Kafka 丰富很多,这也是很多业务系统选择它的原因。

5.1 消息过滤(Tag)

假设你有一个user-events主题,里面有各种用户事件:注册、登录、下单、评论…

Kafka 的做法

// 消费者拿到所有消息,自己过滤for(ConsumerRecordrecord:records){UserEventevent=parse(record);if(event.getType().equals("ORDER")){// 处理订单事件}// 其他事件直接丢弃}

问题:消费者要拉取所有消息,然后手动过滤,浪费带宽和 CPU。

RocketMQ 的做法

// 生产者发送时打上 TagMessagemsg=newMessage("user-events","ORDER",data);// 消费者订阅时指定 Tag,只拉取需要的消息consumer.subscribe("user-events","ORDER");

Broker 端直接过滤,消费者只收到自己关心的消息。

5.2 事务消息

两者都支持事务,但含义不同。

Kafka 的事务

保证生产者发送的多条消息,要么全部成功,要么全部失败。

producer.beginTransaction();producer.send(msg1);producer.send(msg2);producer.send(msg3);producer.commitTransaction();// 三条消息原子性提交

这只是发送端的事务

RocketMQ 的事务

保证发消息本地业务操作要么同时成功,要么同时失败。

1. 发送半消息(Half Message)到 Broker,消费者暂时看不到 2. 执行本地事务(比如扣款) 3. 根据本地事务结果,提交或回滚消息

举个例子

用户下单扣款场景:

  • 发送"扣款成功"消息到 MQ
  • 执行数据库扣款操作

如果消息发了,但数据库扣款失败了怎么办?RocketMQ 的事务消息可以保证两者一致性。

5.3 延迟队列

场景:用户下单后 30 分钟未支付,自动取消订单。

RocketMQ:原生支持延迟消息

Messagemsg=newMessage("order-timeout",data);msg.setDelayTimeLevel(5);// 延迟级别,比如 5 代表 1 分钟producer.send(msg);

Kafka:不支持,需要自己实现(比如用定时任务扫描)。

5.4 死信队列

消费失败的消息去哪了?

RocketMQ:自动进入死信队列(Dead Letter Queue),方便后续排查和重试。

Kafka:原生不支持,需要自己实现(比如消费失败后手动发到另一个 Topic)。

5.5 消息回溯

想重新消费历史消息怎么办?

功能KafkaRocketMQ
按 Offset 回溯✅ 支持✅ 支持
按时间回溯✅ 支持(0.10.1+)✅ 支持

这个功能两者都有,Kafka 从 0.10.1 版本后也支持按时间回溯了。

5.6 功能对比总结

功能KafkaRocketMQ
消息过滤(Tag)❌ 不支持✅ 支持
事务消息⚠️ 仅发送端事务✅ 分布式事务
延迟队列❌ 不支持✅ 支持
死信队列❌ 不支持✅ 支持
消息回溯✅ 支持✅ 支持

六、性能差异的根本原因

前面说了,Kafka 性能(17万/秒)比 RocketMQ(10万/秒)高不少。RocketMQ 参考了 Kafka 的设计,为什么性能反而不如?

答案是:零拷贝技术的选择不同

6.1 什么是零拷贝

消息队列的数据存在磁盘上。消费者要读取消息,数据需要从磁盘发送到网络。

传统方式(没有零拷贝):

磁盘 → 内核缓冲区 → 用户空间 → Socket缓冲区 → 网卡 (拷贝1) (拷贝2) (拷贝3) (拷贝4)

4 次拷贝,2 次系统调用,效率很低。

6.2 两种零拷贝方案

方案一:mmap(内存映射)

磁盘 → 内核缓冲区 ←映射→ 用户空间 → Socket缓冲区 → 网卡 (拷贝1) (不拷贝) (拷贝2) (拷贝3)

省掉了内核到用户空间的拷贝,还剩 3 次。

关键点:用户空间可以直接访问数据内容

方案二:sendfile

磁盘 → 内核缓冲区 → 网卡 (DMA拷贝) (DMA拷贝)

只有 2 次拷贝,而且都是 DMA 控制器在干活,不占用 CPU

关键点:用户空间完全不参与,也看不到数据内容

6.3 为什么 RocketMQ 不用 sendfile

看一下两个函数的返回值:

// mmap - 返回数据内容的指针void*mmap(void*addr,size_tlength,...);// sendfile - 返回发送了多少字节ssize_tsendfile(intout_fd,intin_fd,off_t*offset,size_tcount);
  • mmap:应用层能拿到消息内容,可以做各种处理
  • sendfile:应用层只知道发了多少字节,不知道具体内容是什么

RocketMQ 的很多功能需要读取消息内容

  • 消息过滤:需要读取 Tag
  • 死信队列:需要知道是哪条消息失败了
  • 事务消息:需要根据消息内容做二次投递

如果用 sendfile,根本拿不到消息内容,这些功能就没法实现了。

所以

消息队列零拷贝方案原因
Kafkasendfile追求极致性能,不需要读取消息内容
RocketMQmmap需要读取消息内容来实现丰富功能

这就是 RocketMQ 性能不如 Kafka 的根本原因。


七、如何选型

说了这么多,到底该选哪个?

7.1 选 Kafka 的场景

  • 大数据场景:日志采集、实时计算、数据管道
  • 关键词:Spark、Flink、Hadoop、数据湖、ETL
  • 特点:数据量巨大,对吞吐量要求极高,功能需求简单
日志服务 → Kafka → Flink → 数据仓库 用户行为 → Kafka → Spark → 实时分析

7.2 选 RocketMQ 的场景

  • 业务系统场景:电商、金融、订单、支付
  • 关键词:事务、延迟、重试、可靠性
  • 特点:功能需求复杂,对可靠性要求高,数据量相对可控
订单服务 → RocketMQ → 库存服务 支付服务 → RocketMQ(事务消息) → 积分服务

7.3 简单粗暴的选型标准

场景推荐
能频繁听到 Spark、Flink 这些词Kafka
其他业务场景RocketMQ

八、总结

本文从架构、存储、功能、性能四个维度对比了 Kafka 和 RocketMQ:

维度KafkaRocketMQ
元数据管理Zookeeper(正在移除)NameServer(轻量)
存储模型每个 Partition 存完整消息CommitLog 统一存储
多 Topic 写入可能退化为随机写顺序写,性能更好
主从同步按 Partition 同步按 Broker 同步整个 CommitLog
功能丰富度基础功能消息过滤、事务、延迟、死信队列
零拷贝sendfilemmap
吞吐量~17万/秒~10万/秒

核心结论

没有完美的架构,只有适合的场景。Kafka 追求极致性能,RocketMQ 追求功能丰富。做架构,做到最后,都是在做折中


热门专栏推荐

  • Agent小册
  • Java基础合集
  • Python基础合集
  • Go基础合集
  • 大数据合集
  • 前端小册
  • 数据库合集
  • Redis 合集
  • Spring 全家桶
  • 微服务全家桶
  • 数据结构与算法合集
  • 设计模式小册
  • 消息队列合集

等等等还有许多优秀的合集在主页等着大家的光顾,感谢大家的支持

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😊
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🙏
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🌟

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 0:05:30

SPOD频谱正交分解:流体动力学模态分析的终极指南

频谱正交分解(SPOD)作为频域模态分析的核心技术,在流体力学和振动工程领域展现出强大的应用价值。这项技术能够从平稳随机过程中提取最优的动态结构模式,为工程师和研究人员提供深入的物理洞察。 【免费下载链接】spod_matlab Spectral proper orthogona…

作者头像 李华
网站建设 2026/2/3 0:05:46

5、客户端 - 服务器纯 IP 网络配置与使用指南

客户端 - 服务器纯 IP 网络配置与使用指南在当今的网络环境中,确保网络连接的安全性和高效性至关重要。OpenVPN 作为一款强大的虚拟专用网络(VPN)工具,为我们提供了多种解决方案。本文将详细介绍 OpenVPN 在客户端 - 服务器纯 IP …

作者头像 李华
网站建设 2026/2/5 3:08:30

腾讯HunyuanVideo 1.5:颠覆性轻量级AI视频生成技术全面解析

腾讯HunyuanVideo 1.5:颠覆性轻量级AI视频生成技术全面解析 【免费下载链接】HunyuanVideo 项目地址: https://ai.gitcode.com/hf_mirrors/tencent/HunyuanVideo 在AI视频生成技术快速发展的2025年,腾讯混元团队正式开源HunyuanVideo 1.5模型&am…

作者头像 李华
网站建设 2026/2/3 0:05:44

3分钟学会文本转SVG:让你的文字变成精美矢量图形

3分钟学会文本转SVG:让你的文字变成精美矢量图形 【免费下载链接】text-to-svg Convert text to SVG path without native dependence. 项目地址: https://gitcode.com/gh_mirrors/te/text-to-svg 还在为普通文本缺乏设计感而烦恼吗?text-to-svg这…

作者头像 李华
网站建设 2026/2/3 0:31:55

fpm工具实战:R项目跨平台部署完整指南

fpm工具实战:R项目跨平台部署完整指南 【免费下载链接】fpm Effing package management! Build packages for multiple platforms (deb, rpm, etc) with great ease and sanity. 项目地址: https://gitcode.com/gh_mirrors/fp/fpm 在R语言项目开发过程中&…

作者头像 李华