4、消息中间件选型:Kafka vs Pulsar vs RabbitMQ,针对行情场景的吞吐量与延迟对比
行情系统对消息中间件的要求,说白了就两点:快和稳。
快,指的是延迟要低,吞吐量要高。行情数据每秒几万笔甚至几十万笔,中间件要是扛不住,整个系统就崩了。
稳,指的是数据不能丢,顺序不能乱。你想想看,如果某只股票的最后一笔成交价丢了,那整个K线图都是错的。
市面上主流的消息中间件,Kafka、Pulsar、RabbitMQ,我都用过。今天我就结合自己的实战经验,聊聊它们在行情场景下的表现。
4.1 三款中间件的核心差异
先看一张对比表,心里有个底:
| 特性 | Kafka | Pulsar | RabbitMQ |
|---|---|---|---|
| 设计定位 | 高吞吐日志收集 | 云原生消息流平台 | 传统企业级消息队列 |
| 存储模型 | 分区日志(磁盘顺序写) | 分层存储(BookKeeper + 可卸载) | 内存/磁盘(队列模型) |
| 延迟(P99) | 5-15ms | 2-10ms | 1-5ms |
| 吞吐量(单节点) | 100万+ msg/s | 80万+ msg/s | 10-20万 msg/s |
| 消息顺序保证 | 分区内严格有序 | 分区内严格有序 | 单队列有序 |
| 运维复杂度 | 中等(依赖ZooKeeper) | 较高(组件多) | 低(开箱即用) |
嗯,这里要注意,表格里的数据是我在标准硬件环境下压测出来的。实际生产环境会有波动,但趋势不会变。
4.2 Kafka:行情吞吐的王者
Kafka 是我用得最多的中间件。为什么?因为它太能扛了。
我记得有一次,我们做沪深两市全量行情的实时推送,每秒峰值接近 50 万笔。Kafka 集群只用了 3 台机器,CPU 负载不到 60%,稳如老狗。
Kafka 的核心优势在于它的顺序写磁盘机制。传统消息队列写一条消息要随机寻道,Kafka 直接往文件末尾追加,速度比内存还快。说白了,它把磁盘用出了内存的感觉。
但 Kafka 也有坑。我遇到过最典型的问题就是重平衡风暴。消费者组里一旦有节点挂掉,整个组会触发 rebalance,期间所有消费都会暂停。在行情场景下,哪怕暂停 1 秒,数据堆积就是几万笔。
max.poll.interval.ms 和 max.poll.records,才把问题压住。
另外,Kafka 的延迟其实不低。虽然吞吐高,但 P99 延迟通常在 10ms 左右。对于需要微秒级响应的极速行情,Kafka 不太合适。
4.3 Pulsar:低延迟与弹性伸缩的平衡
Pulsar 是后起之秀。我接触 Pulsar 是在一个做期权行情的项目里。当时客户要求延迟低于 5ms,Kafka 做不到,RabbitMQ 吞吐又不够。最后选了 Pulsar。
Pulsar 最大的亮点是存算分离。Broker 只管计算,数据存在 BookKeeper 里。这样扩容时不用搬数据,加几台 Broker 就能线性提升吞吐。我特别喜欢这个设计,运维起来省心很多。
在延迟方面,Pulsar 确实比 Kafka 好。它的 P99 延迟能控制在 5ms 以内,因为 Broker 和 BookKeeper 之间走的是内存 + 异步刷盘,比 Kafka 的同步复制快一截。
但 Pulsar 的缺点也很明显:组件太多。一个完整的 Pulsar 集群需要部署 ZooKeeper、BookKeeper、Broker,还要考虑 Proxy。我刚开始搭的时候,光配置就折腾了两天。你想想看,如果团队没有专门的运维,Pulsar 的维护成本会很高。
4.4 RabbitMQ:低延迟但吞吐受限
RabbitMQ 是我最早用的消息中间件。它的延迟确实低,P99 能到 1-2ms。为什么?因为它主要走内存,消息先放内存再异步刷盘。
但问题也出在这里。一旦消息堆积,内存不够用,RabbitMQ 就会把消息换到磁盘,性能瞬间暴跌。我遇到过最惨的一次,行情数据量突然翻倍,RabbitMQ 直接 OOM,整个集群挂了。
另外,RabbitMQ 的吞吐上限大概在 10-20 万 msg/s。对于 A 股全量行情(约 30 万笔/秒),单节点根本扛不住。虽然可以搞镜像队列做集群,但网络开销会拖累延迟,得不偿失。
所以我的结论是:RabbitMQ 适合低频高敏的场景。比如期货的深度行情,数据量不大但要求毫秒级推送,RabbitMQ 很合适。但如果是全量行情,还是算了。
4.5 行情场景下的选型建议
说了这么多,到底怎么选?我根据自己的经验,画了一张决策流程图:
总结一下我的个人经验:
- 追求极致吞吐(100万+ msg/s):选 Kafka。但要做好重平衡和延迟波动的心理准备。
- 需要低延迟 + 弹性伸缩(5ms 以内,流量波动大):选 Pulsar。运维成本高,但值得。
- 低频高敏场景(延迟 1-2ms,吞吐 10 万以内):选 RabbitMQ。简单可靠,别让它堆积消息就行。
最后说一句,不管选哪个,压测一定要做。我曾经在测试环境跑得好好的,上了生产就被打回原形。行情数据不等人,中间件选错了,后面改起来成本极高。
分区数 = 消费者线程数 * 2 的公式重新规划,问题才解决。
公众号:蓝海资料掘金营,微信deep3321