Kafka vs RocketMQ 深度技术选型对比
前言
在分布式系统架构中,消息中间件是实现系统解耦、异步处理、削峰填谷的核心组件。作为 Java 开发者,在技术选型时经常面临 Kafka 和 RocketMQ 的选择困境。本文将从技术架构、核心特性、性能优化、实际应用场景等多个维度深入对比两者,为技术选型提供决策依据。
一、技术架构深度对比
1.1 存储架构
Kafka 存储架构
核心设计思想: 顺序写磁盘 + PageCache + 零拷贝
Topic: order-topic (3 partitions)
partition-0/
├── 00000000000000000000.log # Segment 文件(默认 1GB)
├── 00000000000000000000.index # 稀疏索引(offset → 物理位置)
├── 00000000000000000000.timeindex # 时间索引(timestamp → offset)
├── 00000000000005368709.log # 下一个 Segment
├── 00000000000005368709.index
└── 00000000000005368709.timeindex
日志分段机制:
- 文件命名规则: 以当前 segment 的第一条消息 offset 命名
- 分段优势:
- 快速删除过期数据: 直接删除整个 Segment 文件,O(1) 时间复杂度
- 加速查找: 通过二分查找定位到具体 Segment,再通过索引定位消息
- 限制单文件大小: 避免单个文件过大影响性能
索引机制:
稀疏索引结构(.index):
┌────────────┬─────────────┐
│ Offset │ Position │ # 相对偏移量 → 物理字节位置
├────────────┼─────────────┤
│ 0 │ 0 │
│ 500 │ 20480 │ # 每隔 N 条消息建一个索引
│ 1000 │ 40960 │
└────────────┴─────────────┘
查找步骤:
1. 二分查找定位 Segment 文件
2. 在索引文件中二分查找最近的索引点
3. 从索引位置顺序扫描到目标消息
性能优化:
- PageCache 机制: 利用操作系统页缓存,避免频繁磁盘 IO
- 零拷贝技术: 使用 sendfile 系统调用,减少数据拷贝次数
- 顺序写: 磁盘顺序写性能接近内存随机写
劣势:
- 随机读性能较差: 需要从 Segment 文件顺序扫描
- 不支持按 Key 查询: 必须知道 partition + offset
- 历史消息查询效率低
RocketMQ 存储架构
核心设计思想: CommitLog + ConsumeQueue 分离架构
消息存储结构:
$HOME/store/
├── commitlog/ # 所有消息统一写入(顺序写)
│ ├── 00000000000000000000
│ └── 00000000001073741824 # 单文件默认 1GB
│
├── consumequeue/ # 队列索引文件(按 Topic+QueueId 组织)
│ ├── TopicTest/
│ │ ├── 0/00000000000000000000
│ │ ├── 1/00000000000000000000
│ │ └── 2/00000000000000000000
│
└── index/ # Hash 索引(支持按 Key/时间查询)
└── 20250226010203456
存储流程:
1. Producer 发送消息
↓
2. 写入 CommitLog(顺序追加,所有 Topic 共享)
↓
3. 异步构建 ConsumeQueue(每个 Topic-Queue 独立索引)
├── 存储内容:CommitLog Offset + Size + TagHashCode
└── 单条索引固定 20 字节
↓
4. 异步构建 IndexFile(可选,支持按 Key 查询)
ConsumeQueue 结构:
每条索引固定 20 字节:
┌──────────────┬──────┬──────────────┐
│ CommitLog │ Size │ Tag HashCode │
│ Offset(8B) │ (4B) │ (8B) │
└──────────────┴──────┴──────────────┘
优势:
- 索引文件极小,全部加载到内存
- 消费时先读索引,再根据 offset 到 CommitLog 读消息
- 支持多个 Consumer 订阅同一 Topic 不同 Tag
IndexFile 索引机制:
支持按以下维度查询:
- 按 MessageKey 查询(精确匹配)
- 按时间范围查询
- 按 Topic 查询
索引结构(Hash 索引):
┌─────────────┐
│ Header │ # 元数据(起止时间等)
├─────────────┤
│ Hash Slot │ # Hash 槽(500万个槽)
├─────────────┤
│ Index Entry │ # 索引项(链表结构解决冲突)
└─────────────┘
性能优化:
- 读写分离: 写走 CommitLog,读走 ConsumeQueue
- 零拷贝: 使用 mmap + write 方式
- 异步刷盘: 支持同步/异步刷盘策略
- 索引加速: ConsumeQueue 加载到内存,消费速度快
优势:
- 支持按 Key 查询消息
- 支持按时间范围查询
- 支持消息轨迹追踪
- ConsumeQueue 小且快,消费性能高
劣势:
- 存储结构复杂,维护成本高
- 异步构建索引有延迟
- 磁盘空间占用相对较大
1.2 集群架构
Kafka 集群架构
┌──────────────────────────────────────────┐
│ ZooKeeper / KRaft │
│ - Broker 元数据管理 │
│ - Controller 选举 │
│ - Topic 配置管理 │
└────────────┬─────────────────────────────┘
│
┌────────┴────────┬────────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Broker-1│ │ Broker-2│ │ Broker-3│
│ (Leader)│ │(Replica)│ │(Replica)│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└─────────────────┴────────────┘
Partition-0
(Replication=3)
核心组件:
- Controller: 集群控制器,负责 Partition Leader 选举
- Broker: 消息存储节点
- ZooKeeper/KRaft: 元数据管理(Kafka 3.x+ 支持 KRaft 去 ZK)
分区副本机制:
ISR(In-Sync Replicas)机制:
Leader: Broker-1 [offset: 10000]
↓ 同步复制
Replica: Broker-2 [offset: 9998] ✓ 在 ISR 中(滞后 < 10s)
Replica: Broker-3 [offset: 9500] ✗ 踢出 ISR(滞后 > 10s)
ISR 判断条件:
- replica.lag.time.max.ms (默认 10s)
- Follower 最后一次 Fetch 请求时间 < 10s
高可用保障:
- Leader 选举: 从 ISR 中选举新 Leader
- min.insync.replicas: 最少同步副本数(例如设置为 2)
- acks=all: Producer 等待所有 ISR 副本确认
优势:
- 架构简单,易于理解
- 去 ZK 化(KRaft 模式)减少依赖
- 副本机制成熟稳定
劣势:
- Leader 选举依赖 ISR,极端情况可能无法选举
- 不支持主从自动切换(需等待 ISR 恢复)
RocketMQ 集群架构
┌──────────────────────────────────────────┐
│ NameServer Cluster (无状态) │
│ - 路由信息管理 │
│ - Broker 心跳监听 │
└────────────┬─────────────────────────────┘
│ 心跳上报
┌────────┴────────┬────────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Master-1│←────→│ Slave-1 │ │ Master-2│
│ │ 同步 │ │ │ │
└─────────┘ └─────────┘ └─────────┘
│ │ │
└────────────────┴────────────┘
Producer/Consumer
核心组件:
- NameServer: 轻量级注册中心(无状态,相互独立)
- Broker Master: 处理读写请求
- Broker Slave: 消息备份,可承担读请求
主从复制机制:
复制方式:
1. 同步复制(SYNC_MASTER)
Master 写入后等待 Slave 同步完成再返回
✓ 高可靠
✗ 性能损失
2. 异步复制(ASYNC_MASTER)
Master 写入后立即返回
✓ 高性能
✗ 可能丢消息
3. 半同步复制(推荐)
重要消息同步,普通消息异步
高可用机制 (RocketMQ 5.x):
DLedger Controller 模式:
┌─────────────────────────────────────┐
│ DLedger Controller (基于 Raft) │
│ - 自动 Master 选举 │
│ - 元数据管理 │
└─────────────┬───────────────────────┘
│
┌─────────┴─────────┬──────────┐
↓ ↓ ↓
┌────────┐ ┌────────┐ ┌────────┐
│ Broker │ │ Broker │ │ Broker │
│ Master │ │ Slave │ │ Slave │
└────────┘ └────────┘ └────────┘
Master 故障后:
1. Controller 检测到 Master 宕机
2. 从 Slave 中选举新 Master (基于 Raft 日志完整性)
3. 自动切换路由,秒级恢复
Slave Acting Master (SAM) 机制:
Slave 可临时接管 Master 角色:
1. Master 宕机
2. Slave 切换为 Acting Master(可读可写)
3. 原 Master 恢复后自动降级为 Slave
优势:
- NameServer 无状态,易于扩展
- 支持主从自动切换(5.x)
- 消息可靠性高(同步复制 + 主从切换)
劣势:
- 集群架构复杂
- 需要配置主从关系
- 4.x 版本主从切换需人工介入
1.3 数据复制架构
Kafka 数据复制
Replication 流程:
Producer
↓ acks=all
Leader (Broker-1)
↓ 写入本地 Log
↓ 等待 Follower Fetch
├──→ Follower-1 (Broker-2) [Fetch Request]
│ ↓ 写入本地 Log
│ ↓ 发送 ACK
└──→ Follower-2 (Broker-3) [Fetch Request]
↓ 写入本地 Log
↓ 发送 ACK
↓ 收到所有 ISR ACK
返回 Producer 成功
HW (High Watermark) 机制:
Partition-0:
Leader: [msg1][msg2][msg3][msg4][msg5]
─────────────────────↑ LEO (Log End Offset)
────────────────↑ HW (High Watermark)
Follower-1: [msg1][msg2][msg3][msg4]
Follower-2: [msg1][msg2][msg3][msg4]
HW = min(所有 ISR 副本的 LEO)
Consumer 只能读到 HW 之前的消息(已提交消息)
优势:
- Follower 主动拉取,减轻 Leader 压力
- HW 机制保证消息可见性一致
劣势:
- 复制延迟取决于 Follower Fetch 频率
- ISR 收缩可能导致可用性下降
RocketMQ 数据复制
同步复制流程:
Producer
↓
Master
↓ 写入 CommitLog
↓ 推送给 Slave
Slave
↓ 写入 CommitLog
↓ 返回 ACK
Master
↓ 返回 Producer 成功
CommitLog 复制机制:
Master CommitLog:
[msg1][msg2][msg3][msg4][msg5]
↓ 实时推送(HAService)
Slave CommitLog:
[msg1][msg2][msg3][msg4]
复制延迟监控:
slaveFallBehindMuch = Master Offset - Slave Offset
Quorum 写机制 (RocketMQ 5.x):
多副本写入策略:
┌──────────────┬──────────┬──────────┐
│ 写入策略 │ 副本数 │ 性能 │
├──────────────┼──────────┼──────────┤
│ 同步双写 │ ≥2 │ 低 │
│ 同步多写 │ ≥3 │ 最低 │
│ 自适应降级 │ 动态调整 │ 平衡 │
└──────────────┴──────────┴──────────┘
自适应降级逻辑:
1. 正常情况:同步写 3 副本
2. 某副本延迟 > 阈值:降级为同步写 2 副本
3. 延迟恢复:自动恢复 3 副本同步
优势:
- 主动推送复制,延迟低
- 支持灵活的复制策略
- Quorum 机制提升可用性
劣势:
- 同步复制性能损耗大
- 主从关系固定,不如 Kafka 灵活
1.4 消费模型架构
Kafka 消费模型
Consumer Group 模型:
Topic: order-topic (4 partitions)
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│ P-0 │ │ P-1 │ │ P-2 │ │ P-3 │
└───┬──┘ └───┬──┘ └───┬──┘ └───┬──┘
│ │ │ │
↓ ↓ ↓ ↓
┌──────────────────────────────────────┐
│ Consumer Group: order-service │
│ ├── Consumer-1 (消费 P-0, P-1) │
│ └── Consumer-2 (消费 P-2, P-3) │
└──────────────────────────────────────┘
核心原则:
- 分区是最小并行单位: 一个分区只能被 Consumer Group 内一个 Consumer 消费
- Consumer 数量 ≤ Partition 数量: 超过的 Consumer 空闲
- Rebalance: Consumer 加入/退出时触发重新分配
Offset 管理:
Kafka 存储 Offset 位置:
__consumer_offsets (内部 Topic)
├── Key: (GroupId, Topic, Partition)
└── Value: Offset
提交方式:
1. 自动提交(enable.auto.commit=true)
- 每 5s 自动提交一次
- 风险:可能丢消息或重复消费
2. 手动提交(推荐)
- commitSync(): 同步提交
- commitAsync(): 异步提交
优势:
- 简单高效,天然支持分区并行
- Consumer 自主管理 Offset
- 支持任意位置重置 Offset
劣势:
- Consumer 数量受限于 Partition 数量
- Rebalance 期间停止消费
- 不支持按消息属性过滤
RocketMQ 消费模型
集群消费(Clustering):
Topic: order-topic (4 queues)
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│ Q-0 │ │ Q-1 │ │ Q-2 │ │ Q-3 │
└───┬──┘ └───┬──┘ └───┬──┘ └───┬──┘
│ │ │ │
↓ ↓ ↓ ↓
┌──────────────────────────────────────┐
│ Consumer Group: order-service │
│ ├── Consumer-1 (消费 Q-0, Q-1) │
│ └── Consumer-2 (消费 Q-2, Q-3) │
└──────────────────────────────────────┘
广播消费(Broadcasting):
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│ Q-0 │ │ Q-1 │ │ Q-2 │ │ Q-3 │
└───┬──┘ └───┬──┘ └───┬──┘ └───┬──┘
│ │ │ │
├─────────┼─────────┼─────────┤
↓ ↓ ↓ ↓
Consumer-1 Consumer-2 ...(每个都消费全量)
Push vs Pull 模式:
Push 模式(实际是长轮询):
Consumer
↓ PullRequest (timeout=30s)
Broker
↓ 有消息立即返回,无消息挂起
↓ 30s 内有新消息主动推送
Consumer
↓ 消费消息
↓ 发送新的 PullRequest
优势:
- 实时性高
- 简化开发
POP 消费模式 (RocketMQ 5.x 新特性):
传统 Pull 模式问题:
- Consumer 需要维护队列分配关系
- Rebalance 逻辑复杂
- 客户端负担重
POP 模式:
Consumer
↓ Pop Request (无需指定队列)
Broker
↓ 自动分配消息
↓ 返回消息 + InvisibleTime
Consumer
↓ 消费成功后 ACK
↓ 消费失败或超时自动重新可见
优势:
- 无需 Rebalance
- 支持无限扩展 Consumer
- 类似 SQS/RabbitMQ 的消费体验
消息过滤:
支持多种过滤方式:
1. Tag 过滤(服务端过滤)
consumer.subscribe("TopicTest", "TagA || TagB");
2. SQL92 过滤
consumer.subscribe("TopicTest",
MessageSelector.bySql("age > 18 AND region = 'SH'"));
3. 类过滤模式(自定义 FilterServer)
优势:
- 支持广播消费
- 支持消息过滤
- POP 模式简化客户端逻辑
- Consumer 数量不受队列限制
劣势:
- Push 模式复杂度高
- 消费进度管理需依赖 Broker
1.5 网络通信架构
Kafka 网络架构
Kafka 网络线程模型(Reactor 模型):
┌─────────────────────────────────────┐
│ Acceptor Thread (1个) │
│ ↓ 接受连接 │
│ ↓ 分配给 Processor │
└───────────┬─────────────────────────┘
│
┌───────┴───────┬──────────┐
↓ ↓ ↓
┌────────┐ ┌────────┐ ┌────────┐
│Processor│ │Processor│ │Processor│ # 网络线程(num.network.threads=3)
│Thread-1│ │Thread-2│ │Thread-3│
└────┬───┘ └────┬───┘ └────┬───┘
│ │ │
└─────────────┴──────────┘
↓
┌────────────────────┐
│ Request Queue │ # 请求队列
└────────┬───────────┘
│
┌────────┴───────┬──────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Handler │ │ Handler │ │ Handler │ # IO 线程(num.io.threads=8)
│ Thread-1│ │ Thread-2│ │ Thread-3│
└─────────┘ └─────────┘ └─────────┘
↓ ↓ ↓
┌──────────────────────────────────────┐
│ Response Queue │
└──────────────────────────────────────┘
协议: 自定义二进制协议(高性能)
连接复用: Producer/Consumer 与 Broker 保持长连接
RocketMQ 网络架构
RocketMQ 网络模型(基于 Netty):
┌─────────────────────────────────────┐
│ Netty Boss Thread │
│ ↓ 接受连接 │
└───────────┬─────────────────────────┘
│
┌───────┴───────┬──────────┐
↓ ↓ ↓
┌────────┐ ┌────────┐ ┌────────┐
│ Worker │ │ Worker │ │ Worker │ # Netty IO 线程
│Thread-1│ │Thread-2│ │Thread-3│
└────┬───┘ └────┬───┘ └────┬───┘
│ │ │
└─────────────┴──────────┘
↓
┌────────────────────┐
│ Business ThreadPool│ # 业务线程池(按请求类型分)
├────────────────────┤
│ SendMessageThreadPool (8 threads) │
│ PullMessageThreadPool (16 threads) │
│ QueryMessageThreadPool (4 threads) │
│ AdminThreadPool (4 threads) │
└────────────────────┘
协议:
- Remoting 协议(默认,兼容性好)
- gRPC 协议(RocketMQ 5.x,多语言支持)
优势:
- Netty 高性能网络框架
- 业务线程池隔离,避免相互影响
- 支持多种协议
二、生产者/消费者端优化对比
2.1 生产者端优化
Kafka Producer 批量发送
// Kafka Producer 配置
Properties props = new Properties();
// 1. 批量发送配置
props.put("batch.size", 32768); // 32KB,达到此大小立即发送
props.put("linger.ms", 10); // 等待 10ms 凑批
props.put("buffer.memory", 33554432); // 32MB 缓冲区
props.put("compression.type", "lz4"); // 压缩算法
// 2. 可靠性配置
props.put("acks", "all"); // 等待所有 ISR 确认
props.put("retries", 3); // 重试 3 次
props.put("max.in.flight.requests.per.connection", 1); // 保证顺序
// 3. 性能配置
props.put("send.buffer.bytes", 131072); // Socket 发送缓冲区 128KB
props.put("receive.buffer.bytes", 32768); // Socket 接收缓冲区 32KB
批量发送原理:
Producer 发送流程:
用户线程
↓ send(record)
RecordAccumulator (内存缓冲区)
├── Partition-0
│ ├── Batch-1 (32KB) → 满了,触发发送
│ └── Batch-2 (16KB) → 等待中
├── Partition-1
│ └── Batch-1 (8KB) → linger.ms 超时也发送
│
↓ Sender 线程(后台 IO 线程)
↓ 压缩(lz4/snappy/gzip)
↓ 网络发送(批量)
Broker
发送时机:
- Batch 大小达到
batch.size linger.ms时间到达- 内存缓冲区满 (
buffer.memory) - 手动 flush()
性能提升:
- 批量发送减少网络往返
- 压缩提升网络传输效率
- 顺序写磁盘提升 Broker 写入性能
RocketMQ Producer 批量发送
// RocketMQ Producer 配置
DefaultMQProducer producer = new DefaultMQProducer("producer_group");
// 1. 批量发送
List<Message> messages = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Message msg = new Message("TopicTest", "TagA",
("Hello RocketMQ " + i).getBytes());
messages.add(msg);
}
// 批量发送(单次最大 4MB)
SendResult sendResult = producer.send(messages);
// 2. 异步发送
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功");
}
@Override
public void onException(Throwable e) {
System.out.println("发送失败: " + e.getMessage());
}
});
// 3. 单向发送(最高性能,不关心结果)
producer.sendOneway(msg);
RocketMQ 5.x 批量优化:
批量消息压缩优化:
1. 单条消息不压缩
2. 批量消息统一压缩(减少 CPU 开销)
3. 支持按大小自动分批(maxMessageSize=4MB)
批量发送限制:
- 同一批消息必须:
✓ 相同 Topic
✓ 不支持延迟消息
✓ 不支持事务消息
性能对比:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 自动批量 | ✅ 自动凑批 | ❌ 需手动批量 |
| 压缩支持 | ✅ lz4/snappy/gzip | ✅ zip/lz4 |
| 批量大小限制 | 受 batch.size 限制 | 单次最大 4MB |
| 异步发送 | ✅ 支持 | ✅ 支持 |
2.2 消费者端优化
Kafka Consumer 优化
// Kafka Consumer 配置
Properties props = new Properties();
// 1. 批量拉取配置
props.put("fetch.min.bytes", 1024); // 最小拉取 1KB
props.put("fetch.max.wait.ms", 500); // 最多等待 500ms
props.put("max.partition.fetch.bytes", 1048576); // 单分区最大拉取 1MB
props.put("max.poll.records", 500); // 单次最多拉取 500 条
// 2. Consumer 并行度
props.put("num.consumer.fetchers", 2); // 拉取线程数
// 3. Offset 提交
props.put("enable.auto.commit", false); // 手动提交
props.put("auto.commit.interval.ms", 5000); // 自动提交间隔
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
// 消费逻辑
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
// 批量消费
for (ConsumerRecord<String, String> record : records) {
process(record);
}
// 手动提交 Offset(处理完再提交,保证 At Least Once)
consumer.commitSync();
}
优化策略:
1. 增加分区数提升并行度
- Partition 数 = Consumer 数(最佳)
- 过多 Partition 增加元数据开销
2. 批量拉取 + 批量处理
- fetch.min.bytes:减少网络往返
- max.poll.records:控制单批处理量
3. 异步 Offset 提交
consumer.commitAsync(); // 不阻塞消费
4. 多线程消费
- 单 Consumer 拉取,多线程处理
- 注意线程安全和 Offset 管理
RocketMQ Consumer 优化
// RocketMQ Consumer 配置
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_group");
// 1. 消费线程数配置
consumer.setConsumeThreadMin(20); // 最小线程数
consumer.setConsumeThreadMax(64); // 最大线程数
// 2. 批量消费配置
consumer.setConsumeMessageBatchMaxSize(32); // 单次最多消费 32 条
consumer.setPullBatchSize(32); // 单次拉取 32 条
// 3. 消费并发数
consumer.setPullThresholdForQueue(1000); // 队列最大消息数
consumer.setPullThresholdForTopic(2000); // Topic 最大消息数
// 4. 消息消费超时
consumer.setConsumeTimeout(15); // 15 分钟超时
// 注册监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
// 批量消费(默认并发消费,无序)
for (MessageExt msg : msgs) {
process(msg);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
并发消费 vs 顺序消费:
// 1. 并发消费(高吞吐)
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
// 多线程并发消费,不保证顺序
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 2. 顺序消费(保证顺序)
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeOrderlyContext context) {
// 单线程顺序消费(按队列加锁)
return ConsumeOrderlyStatus.SUCCESS;
}
});
RocketMQ 5.x POP 消费优化:
// POP 消费模式(简化版)
DefaultLitePullConsumer consumer = new DefaultLitePullConsumer("consumer_group");
consumer.setAutoCommit(false);
while (true) {
// 无需指定队列,Broker 自动分配
List<MessageExt> messages = consumer.poll(Duration.ofSeconds(10));
for (MessageExt msg : messages) {
try {
process(msg);
// 消费成功,ACK
consumer.commitSync();
} catch (Exception e) {
// 消费失败,不 ACK(消息自动重新可见)
log.error("消费失败", e);
}
}
}
优势:
- 无需 Rebalance
- 支持无限扩展 Consumer
- 简化客户端逻辑
性能对比:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 批量拉取 | ✅ 自动批量 | ✅ 自动批量 |
| 消费线程池 | ❌ 需自行实现 | ✅ 内置线程池 |
| 顺序消费 | ✅ 分区有序 | ✅ 队列有序 + 全局有序 |
| 消息过滤 | ❌ 不支持 | ✅ Tag/SQL 过滤 |
| 消费重试 | ❌ 需自行实现 | ✅ 自动重试 |
三、核心特性与优劣势对比
3.1 消息顺序性
Kafka 顺序性保证
分区级别顺序:
Producer 保证顺序配置:
props.put("max.in.flight.requests.per.connection", 1); // 同时只有 1 个请求在途
props.put("enable.idempotence", true); // 开启幂等性
发送示例:
// 相同 Key 路由到同一 Partition
producer.send(new ProducerRecord<>("order-topic", orderId, message));
全局有序:
实现方式:
Topic 只设置 1 个 Partition
代价:
- 吞吐量受限(单线程写入)
- 无法并行消费
- 不推荐使用
RocketMQ 顺序性保证
队列级别顺序:
// 发送顺序消息(按 orderId 路由到同一队列)
producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
String orderId = (String) arg;
int index = Math.abs(orderId.hashCode()) % mqs.size();
return mqs.get(index);
}
}, orderId);
全局顺序:
// 创建只有 1 个队列的 Topic
sh mqadmin updateTopic -t OrderTopic -n localhost:9876 -w 1 -r 1
// 消费端顺序消费
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeOrderlyContext context) {
// 单线程顺序消费
return ConsumeOrderlyStatus.SUCCESS;
}
});
顺序消费原理:
RocketMQ 顺序消费锁机制:
1. Consumer 向 Broker 申请队列锁
2. 获得锁后才能消费该队列消息
3. 消费完一批后释放锁
4. 其他 Consumer 无法同时消费同一队列
优势:
- 保证严格顺序
- 支持队列级别并行
劣势:
- 某个消息消费失败会阻塞后续消息
- 消费性能下降
对比总结:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 分区/队列顺序 | ✅ 支持 | ✅ 支持 |
| 全局顺序 | ✅ 支持(1 个分区) | ✅ 支持(1 个队列) |
| 顺序保证机制 | 分区写入顺序 | 队列锁机制 |
| 消费失败处理 | 需手动处理 | 自动阻塞重试 |
3.2 消息可靠性
Kafka 可靠性保证
生产端可靠性:
// 1. ACK 配置
props.put("acks", "all"); // 等待所有 ISR 副本确认
acks=0: 不等待确认(最快,可能丢消息)
acks=1: 等待 Leader 确认(可能丢消息)
acks=all: 等待所有 ISR 确认(最可靠)
// 2. 重试配置
props.put("retries", 3); // 重试 3 次
props.put("retry.backoff.ms", 1000); // 重试间隔 1s
props.put("delivery.timeout.ms", 120000); // 总超时 120s
// 3. 幂等性
props.put("enable.idempotence", true); // 防止重复消息
消费端可靠性:
// 手动提交 Offset(先处理再提交)
consumer.subscribe(Arrays.asList("topic"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
try {
// 1. 处理消息
for (ConsumerRecord<String, String> record : records) {
processMessage(record);
}
// 2. 处理成功后再提交 Offset
consumer.commitSync();
} catch (Exception e) {
log.error("消费失败", e);
// 不提交 Offset,下次重新消费
}
}
可靠性保障:
- 幂等性: 通过 PID + Sequence Number 去重
- 事务: 支持跨分区事务(Exactly Once)
- 副本机制: ISR 保证数据不丢失
RocketMQ 可靠性保证
生产端可靠性:
// 1. 同步发送(等待 Broker 确认)
SendResult sendResult = producer.send(msg);
if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
// 处理发送失败
log.error("发送失败: {}", sendResult);
}
// 2. 同步复制(Master + Slave 都写入成功)
// Broker 配置: brokerRole=SYNC_MASTER
// 3. 发送重试
producer.setRetryTimesWhenSendFailed(3); // 同步发送失败重试 3 次
producer.setRetryTimesWhenSendAsyncFailed(3); // 异步发送失败重试 3 次
消费端可靠性:
// 消费失败自动重试
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
try {
processMessage(msgs);
// 返回成功,Broker 删除消息
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} catch (Exception e) {
log.error("消费失败", e);
// 返回稍后重试(默认最多重试 16 次)
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
});
// 消费重试机制:
// 第1次重试:10s 后
// 第2次重试:30s 后
// 第3次重试:1min 后
// ...
// 第16次重试:2h 后
// 超过 16 次进入死信队列(DLQ)
死信队列机制:
消息重试流程:
原始队列
↓ 消费失败
重试队列(%RETRY%ConsumerGroup)
↓ 重试 16 次仍失败
死信队列(%DLQ%ConsumerGroup)
处理死信消息:
1. 监控死信队列
2. 人工介入处理
3. 修复问题后重新投递
事务消息:
// RocketMQ 事务消息(本地事务 + 消息发送原子性)
TransactionMQProducer producer = new TransactionMQProducer("transaction_group");
producer.setTransactionListener(new TransactionListener() {
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
try {
// 1. 执行本地事务
doLocalTransaction(arg);
// 2. 提交事务
return LocalTransactionState.COMMIT_MESSAGE;
} catch (Exception e) {
// 3. 回滚事务
return LocalTransactionState.ROLLBACK_MESSAGE;
}
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
// 4. 事务状态回查(Broker 定期回查未确定的事务)
boolean success = checkTransactionStatus(msg);
return success ? LocalTransactionState.COMMIT_MESSAGE
: LocalTransactionState.ROLLBACK_MESSAGE;
}
});
// 发送事务消息
producer.sendMessageInTransaction(msg, localTransactionArgs);
可靠性对比:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 生产端确认 | acks=all | 同步发送 + 同步复制 |
| 消费失败处理 | 需自行实现 | 自动重试 + 死信队列 |
| 事务支持 | ✅ Exactly Once | ✅ 事务消息 |
| 消息轨迹 | ❌ 不支持 | ✅ 支持 |
3.3 延迟消息
Kafka 延迟消息
实现方式:
Kafka 原生不支持延迟消息,需自行实现:
方案 1:基于时间轮 + 内部 Topic
1. 发送延迟消息到 delay-topic
2. 消费者轮询 delay-topic
3. 检查消息时间戳,到期后转发到目标 Topic
方案 2:使用外部调度系统
- 延迟消息存储到 Redis/DB
- 定时任务扫描到期消息
- 发送到 Kafka
劣势:
- 需自行开发,复杂度高
- 性能和可靠性需自己保证
RocketMQ 延迟消息
固定延迟级别(4.x):
// 支持 18 个延迟级别
// 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
Message msg = new Message("TopicTest", "TagA", "Hello".getBytes());
// 延迟级别 3 = 10s
msg.setDelayTimeLevel(3);
producer.send(msg);
任意时间延迟(5.x 新特性):
// RocketMQ 5.x 支持任意时间延迟
Message msg = new Message("TopicTest", "TagA", "Hello".getBytes());
// 方式 1:延迟 30 分钟
msg.setDelayTimeSec(1800);
// 方式 2:指定投递时间
long deliverTime = System.currentTimeMillis() + 30 * 60 * 1000;
msg.setDeliverTimeMs(deliverTime);
producer.send(msg);
延迟消息原理:
RocketMQ 延迟消息实现:
1. 延迟消息先写入 SCHEDULE_TOPIC_XXXX
2. 按延迟时间组织到不同队列
3. 定时任务扫描到期消息
4. 转发到原始 Topic
优势:
- 原生支持,无需额外开发
- 性能高,可靠性强
- 5.x 支持任意时间延迟
对比总结:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 原生支持 | ❌ 不支持 | ✅ 支持 |
| 延迟精度 | - | 4.x: 18 个级别 5.x: 任意时间 |
| 实现复杂度 | 高(需自行实现) | 低(开箱即用) |
3.4 消息过滤
Kafka 消息过滤
Kafka 不支持服务端过滤,需客户端过滤:
consumer.subscribe(Arrays.asList("topic"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String, String> record : records) {
// 客户端过滤
if (matchFilter(record)) {
processMessage(record);
}
}
}
劣势:
- 无效消息也需拉取,浪费带宽
- 客户端压力大
RocketMQ 消息过滤
// 1. Tag 过滤(最常用)
// 发送端
Message msg = new Message("TopicTest", "TagA", "Hello".getBytes());
producer.send(msg);
// 消费端(只消费 TagA 或 TagB)
consumer.subscribe("TopicTest", "TagA || TagB");
// 2. SQL92 过滤(需开启 enablePropertyFilter=true)
// 发送端
Message msg = new Message("TopicTest", "TagA", "Hello".getBytes());
msg.putUserProperty("age", "20");
msg.putUserProperty("region", "SH");
producer.send(msg);
// 消费端
consumer.subscribe("TopicTest",
MessageSelector.bySql("age > 18 AND region = 'SH'"));
// 3. 类过滤模式(自定义 Filter)
// 实现 MessageFilter 接口,部署到 FilterServer
过滤原理:
Tag 过滤:
- Tag 的 HashCode 存储在 ConsumeQueue
- 消费时先比对 HashCode(内存操作,快速)
- 匹配后再到 CommitLog 读取完整消息
SQL 过滤:
- 在 Broker 端执行 SQL 表达式
- 只返回匹配的消息给 Consumer
对比总结:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 服务端过滤 | ❌ 不支持 | ✅ 支持 |
| 过滤方式 | - | Tag / SQL / 自定义 |
| 性能影响 | - | 低(索引加速) |
3.5 消息堆积能力
Kafka 消息堆积
堆积能力:
- 基于磁盘存储,容量取决于磁盘大小
- 支持配置消息保留时间(log.retention.hours=168,默认 7 天)
- 支持配置消息保留大小(log.retention.bytes)
堆积性能:
- 顺序读磁盘 + PageCache,性能不会明显下降
- 即使堆积几百 GB 消息,消费性能仍然稳定
清理策略:
1. 基于时间清理(超过 7 天删除)
2. 基于大小清理(超过指定大小删除最老的 Segment)
3. Compaction(保留每个 Key 的最新值)
RocketMQ 消息堆积
堆积能力:
- 基于磁盘存储,容量取决于磁盘大小
- 支持配置消息保留时间(fileReservedTime=72,默认 3 天)
堆积性能:
- CommitLog 顺序写,性能稳定
- ConsumeQueue 索引文件小,全部加载到内存
- 堆积不影响消费性能
清理策略:
1. 定时清理(默认凌晨 4 点)
2. 磁盘空间不足时触发清理(磁盘使用率 > 75%)
对比总结:
| 特性 | Kafka | RocketMQ |
|---|---|---|
| 堆积能力 | ✅ 百万级 TPS 堆积 | ✅ 百万级 TPS 堆积 |
| 堆积对性能影响 | 几乎无影响 | 几乎无影响 |
| 默认保留时间 | 7 天 | 3 天 |
四、优劣势总结
4.1 Kafka 优势
-
超高吞吐量
- 顺序写磁盘 + PageCache + 零拷贝
- 批量发送 + 批量拉取
- 适合日志收集、大数据场景
-
架构简单
- 分区模型易于理解
- 运维成本低
-
生态成熟
- Kafka Streams(流处理)
- Kafka Connect(数据集成)
- 丰富的第三方工具
-
消息堆积能力强
- 堆积不影响性能
- 适合离线数据处理
4.2 Kafka 劣势
-
功能相对简单
- 不支持延迟消息
- 不支持消息过滤
- 不支持消息轨迹
- 消费失败需自行处理
-
消费扩展性受限
- Consumer 数量 ≤ Partition 数量
- 增加 Partition 需重新分配
-
运维复杂
- 依赖 ZooKeeper(虽然 KRaft 已推出)
- 集群扩容需要数据迁移
4.3 RocketMQ 优势
-
功能丰富
- 延迟消息(任意时间延迟)
- 消息过滤(Tag/SQL)
- 事务消息
- 消息轨迹
- 死信队列
-
高可靠性
- 同步复制 + 主从自动切换
- 消费失败自动重试
- 消息轨迹追踪
-
运维友好
- 主从自动切换(5.x)
- 丰富的监控指标
- 控制台管理工具
-
灵活的消费模式
- 集群消费 + 广播消费
- POP 消费(5.x)
- 顺序消费 + 并发消费
4.4 RocketMQ 劣势
-
吞吐量低于 Kafka
- 存储结构复杂(CommitLog + ConsumeQueue)
- 索引维护有开销
-
生态不如 Kafka 成熟
- 第三方集成工具较少
- 社区活跃度不如 Kafka
-
学习成本高
- 概念较多(NameServer、Broker、Queue 等)
- 配置参数复杂
五、技术选型实战案例
案例 1:电商订单系统
场景描述:
- 订单创建后需要通知:库存系统、支付系统、物流系统、积分系统
- 日订单量:100 万
- 高峰 TPS:1 万
- 要求:消息可靠、支持延迟消息(15 分钟未支付自动取消)
技术选型: RocketMQ
理由:
- 延迟消息: 原生支持延迟消息,实现"15 分钟未支付自动取消"逻辑简单
- 事务消息: 保证订单创建与消息发送的原子性
- 消息重试: 自动重试机制提升可靠性
- 消息轨迹: 方便排查订单消息流转问题
架构设计:
// 1. 订单创建 + 事务消息
TransactionMQProducer producer = new TransactionMQProducer("order_producer");
producer.setTransactionListener(new TransactionListener() {
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
Order order = (Order) arg;
try {
// 创建订单(本地事务)
orderService.createOrder(order);
return LocalTransactionState.COMMIT_MESSAGE;
} catch (Exception e) {
return LocalTransactionState.ROLLBACK_MESSAGE;
}
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
// 回查订单状态
String orderId = msg.getKeys();
Order order = orderService.getOrderById(orderId);
return order != null ? LocalTransactionState.COMMIT_MESSAGE
: LocalTransactionState.ROLLBACK_MESSAGE;
}
});
// 发送事务消息
Message msg = new Message("order_topic", "order_created", order.toJson().getBytes());
msg.setKeys(order.getOrderId());
producer.sendMessageInTransaction(msg, order);
// 2. 延迟消息(15 分钟后取消订单)
Message delayMsg = new Message("order_topic", "order_cancel", order.getOrderId().getBytes());
delayMsg.setDelayTimeSec(15 * 60); // 延迟 15 分钟
producer.send(delayMsg);
案例 2:实时数据分析平台
场景描述:
- 采集用户行为日志(点击、浏览、购买等)
- 日志量:10 亿条/天
- 高峰 TPS:10 万+
- 要求:高吞吐、低延迟、支持实时计算
技术选型: Kafka
理由:
- 超高吞吐量: 顺序写 + PageCache + 零拷贝,轻松支持 10 万+ TPS
- 批量发送: 自动凑批,减少网络开销
- 生态集成: 与 Flink/Spark 无缝集成,支持实时计算
- 消息堆积: 支持离线数据回溯分析
架构设计:
// 1. 日志采集(批量发送)
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// 异步发送(高吞吐)
for (UserEvent event : events) {
ProducerRecord<String, String> record = new ProducerRecord<>(
"user_event_topic", event.getUserId(), event.toJson());
producer.send(record, (metadata, exception) -> {
if (exception != null) {
log.error("发送失败", exception);
}
});
}
// 2. 实时计算(Flink 消费 Kafka)
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(
"user_event_topic",
new SimpleStringSchema(),
properties);
DataStream<UserEvent> stream = env.addSource(consumer)
.map(json -> JSON.parseObject(json, UserEvent.class));
// 实时统计:5 分钟窗口内的点击量
stream.filter(event -> "click".equals(event.getEventType()))
.keyBy(UserEvent::getUserId)
.timeWindow(Time.minutes(5))
.sum("clickCount")
.print();
env.execute("Real-time Analytics");
案例 3:微服务系统异步解耦
场景描述:
- 用户注册后需要:发送短信、发送邮件、初始化用户数据、发放优惠券
- 日活:10 万
- TPS:100-500
- 要求:解耦、可靠、消息不丢失
技术选型: RocketMQ 或 Kafka 均可
对比分析:
| 维度 | RocketMQ | Kafka |
|---|---|---|
| 消息可靠性 | ✅ 自动重试 + 死信队列 | ⚠️ 需自行实现重试 |
| 开发成本 | ✅ 低(功能丰富) | ⚠️ 中(需自行封装) |
| 运维成本 | ⚠️ 中(依赖 NameServer) | ✅ 低(生态成熟) |
| 性能 | ✅ 满足需求 | ✅ 满足需求 |
推荐: RocketMQ(开箱即用,降低开发成本)
架构设计:
// 发送端
DefaultMQProducer producer = new DefaultMQProducer("user_producer");
// 用户注册成功后发送消息
Message msg = new Message("user_register_topic", "register", userId.getBytes());
SendResult result = producer.send(msg);
// 消费端(多个系统订阅同一 Topic)
// 1. 短信服务
DefaultMQPushConsumer smsConsumer = new DefaultMQPushConsumer("sms_consumer_group");
smsConsumer.subscribe("user_register_topic", "*");
smsConsumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
sendSms(userId);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
// 2. 邮件服务
DefaultMQPushConsumer emailConsumer = new DefaultMQPushConsumer("email_consumer_group");
emailConsumer.subscribe("user_register_topic", "*");
emailConsumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
sendEmail(userId);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
// 3. 优惠券服务
DefaultMQPushConsumer couponConsumer = new DefaultMQPushConsumer("coupon_consumer_group");
couponConsumer.subscribe("user_register_topic", "*");
couponConsumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
grantCoupon(userId);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
案例 4:日志收集与监控
场景描述:
- 收集微服务日志、应用日志、系统日志
- 日志量:1 TB/天
- 高峰 TPS:5 万+
- 要求:高吞吐、低成本、支持日志回溯
技术选型: Kafka
理由:
- 超高吞吐量: 轻松支持 5 万+ TPS
- 消息堆积: 支持长时间保留(7-30 天)
- 生态集成: 与 ELK(Elasticsearch + Logstash + Kibana)无缝集成
- 成本低: 基于磁盘存储,成本远低于内存存储
架构设计:
日志收集链路:
应用日志 → Filebeat → Kafka → Logstash → Elasticsearch → Kibana
┌──────────┐
│ 微服务 A │ → log file
└──────────┘ ↓
Filebeat
↓
┌──────────┐ Kafka
│ 微服务 B │ → (log_topic)
└──────────┘ ↓
Logstash
┌──────────┐ ↓
│ 微服务 C │ → Elasticsearch
└──────────┘ ↓
Kibana(查询分析)
六、选型决策树
┌─────────────────────────────────────┐
│ 你的业务场景是什么? │
└──────────┬──────────────────────────┘
│
↓
是否需要超高吞吐量?
(TPS > 10 万)
│
┌─────┴─────┐
↓ ↓
是 否
│ │
↓ ↓
选择 Kafka 是否需要延迟消息?
│ │
│ ┌────┴────┐
│ ↓ ↓
│ 是 否
│ │ │
│ ↓ ↓
│ RocketMQ 是否需要消息过滤?
│ │ │
│ │ ┌────┴────┐
│ │ ↓ ↓
│ │ 是 否
│ │ │ │
│ │ ↓ ↓
│ │ RocketMQ 是否需要消息轨迹?
│ │ │ │
│ │ │ ┌────┴────┐
│ │ │ ↓ ↓
│ │ │ 是 否
│ │ │ │ │
│ │ │ ↓ ↓
│ │ │ RocketMQ 两者均可
│ │ │ │ (根据团队经验)
└──────┴────┴────┴──────────┘
七、总结与建议
7.1 选型建议
选择 Kafka 的场景:
- 日志收集、大数据场景(高吞吐量优先)
- 实时数据分析(集成 Flink/Spark)
- 消息不需要复杂功能(延迟、过滤等)
- 团队有 Kafka 运维经验
选择 RocketMQ 的场景:
- 业务消息场景(订单、支付等)
- 需要延迟消息、事务消息
- 需要消息过滤、消息轨迹
- 对消息可靠性要求高
7.2 迁移建议
从 RabbitMQ 迁移到 Kafka/RocketMQ:
- 高吞吐场景 → Kafka
- 业务功能场景 → RocketMQ
从 Kafka 迁移到 RocketMQ:
- 需要延迟消息、消息过滤等功能时考虑
从 RocketMQ 迁移到 Kafka:
- 大数据场景,对生态集成要求高
7.3 最佳实践
Kafka 最佳实践
-
合理设置分区数
- 分区数 = Consumer 数(最佳并行度)
- 不宜过多(增加元数据开销)
-
使用批量发送
- 配置合理的
batch.size和linger.ms - 提升吞吐量
- 配置合理的
-
开启压缩
- 推荐使用
lz4压缩 - 平衡压缩率和性能
- 推荐使用
-
手动提交 Offset
- 先处理再提交,避免丢消息
- 幂等处理,避免重复消费
RocketMQ 最佳实践
-
合理设置队列数
- 队列数 = Consumer 数(最佳并行度)
- 单 Broker 建议 4-8 个队列
-
使用同步发送 + 异步复制
- 平衡性能和可靠性
- 重要消息使用同步复制
-
配置消费线程池
- 根据消息处理耗时调整线程数
- IO 密集型:线程数 = CPU 核数 * 2
- CPU 密集型:线程数 = CPU 核数 + 1
-
监控死信队列
- 定期处理死信消息
- 分析失败原因
7.4 性能对比表
| 维度 | Kafka | RocketMQ |
|---|---|---|
| 单机 TPS | 100 万+ | 10 万+ |
| 消息延迟 | ms 级 | ms 级 |
| 消息堆积 | 百万级 | 百万级 |
| 高可用 | ISR 副本 | 主从自动切换(5.x) |
| 消息可靠性 | 99.99% | 99.99% |
7.5 成本对比
| 成本项 | Kafka | RocketMQ |
|---|---|---|
| 硬件成本 | 低(顺序写,磁盘即可) | 低(顺序写,磁盘即可) |
| 开发成本 | 中(需封装功能) | 低(功能丰富) |
| 运维成本 | 低(生态成熟) | 中(运维工具较少) |
| 学习成本 | 低(概念简单) | 中(概念较多) |
八、未来趋势
Kafka 发展方向
- KRaft 模式成熟:彻底去除 ZooKeeper 依赖
- Tiered Storage:冷热数据分层存储,降低成本
- 云原生:更好的容器化支持
RocketMQ 发展方向
- 存储计算分离:支持云存储(S3、OSS)
- Serverless:按量计费,降低使用门槛
- 多语言 SDK:完善 gRPC 多语言支持
- 流处理:增强 RocketMQ Streams 能力
参考资料
- Apache Kafka 官方文档
- Apache RocketMQ 官方文档
- RocketMQ 5.0 存储计算分离架构
- Kafka KRaft 架构
- 《Kafka 权威指南》
- 《RocketMQ 技术内幕》