消息队列选型,别被Kafka的‘高性能’绑架了

🔑 关键词:消息队列,Kafka,RabbitMQ,Pulsar,选型

📖 摘要:从运维成本和实际业务场景出发,聊聊消息队列选型中那些被忽略的真相。

我在一家做供应链金融的公司待了三年,中间维护过三套消息队列:第一套是Kafka 2.3,第二套是RabbitMQ 3.8,第三套是自研的基于Redis Stream的轻量队列。先说结论:真正需要Kafka的场景,我们一个都没有。 我们当时最大的业务是订单状态变更,峰值QPS大概2000,这个量级用MySQL加个状态字段都绰绰有余。 但架构师因为在上一家公司用Kafka用得顺手,硬是引了进来。 结果就是运维团队要为它专门配三个节点,还要处理分区不平衡、磁盘使用率告警、消费者组rebalance导致的延迟抖动。 后来我翻监控数据,Kafka的平均吞吐利用率连5%都没到。

图片

那些天天吹Kafka吞吐量高的人,很少提它的代价是给客户端和运维带来了多少复杂度。 对比一下RabbitMQ:同样是集群,RabbitMQ的节点状态管理要简单很多,而且它的队列、交换机、绑定模型对于路由和优先级场景是原生支持的。 但RabbitMQ也有它自己的坑——比如镜像队列在节点故障时可能丢消息(除非你用Quorum Queue),再比如它的吞吐量在持久化+confirm模式下会掉得很难看。 我做过一个压测,在双核4G的三节点集群上,RabbitMQ用Quorum Queue跑持久化消息,单队列吞吐只有约8000条/秒,而Kafka轻松突破10万。 问题是,你的业务真的需要10万吗?如果只需要2000,那RabbitMQ带来的可维护性优势,比那多出来的98000更值钱。

图片

Pulsar是这两年火起来的第三极。它把存储和计算拆开,用BookKeeper做日志存储,所以你不用像Kafka那样预先租定分区数量,还能做到秒级扩容。 我第一次在测试环境部署Pulsar的时候,确实被它的架构惊艳到了——同一个topic可以同时用普通消费者和Reader接口,这比Kafka灵活得多。 但部署完我就后悔了:它依赖ZK(虽然已经在去ZK)、BookKeeper、Broker、Proxy,一套最小集群加起来要九个节点以上。 在云上一个月光机器成本就比Kafka贵的多,而且它的延迟在小型集群下并没有优势,反而因为多了层存储路由,p99经常比Kafka高几十毫秒。 所以Pulsar更适合那种需要多租户、超大集群、或者要长期做数据回放的中台团队,普通业务用它就是拿大炮打蚊子,还打不准。

图片

我的独立观点是:消息队列选型的第一步,不是看性能对比图,而是先问自己“这消息到底该不该走队列”。 很多所谓的异步解耦,本质上只是把数据库操作从同步改成异步,但业务上根本不关心这个。比如有个团队把所有HTTP请求都塞进Kafka,再消费去写日志,最后这个topic成为集群里最大的一个,但查日志的人宁愿去ELK搜。 如果只是需要削峰填谷,Redis Stream加一个消费者组就能扛住单机5万以上的写入,而且你完全不用担心分区、rebalance、ISR这些概念。 只有当消息需要被多个不同团队重复消费、需要保存几天以上、或者消费速度必须跟上生产速度时,Kafka那套日志模型才有不可替代的价值。 选型和裁员一样——不是越大的越好,而是谁能活到最后并且不给你添乱,谁才适合你。

图片

最后说说我的运维经验总结:如果你们的团队人数少于10个,没有专职的中间件工程师,业务峰值QPS低于5000,选RabbitMQ(最好用Quorum Queue)。 如果你们是数据密集型团队,需要做流计算、日志采集,而且愿意接受分区扩容的运维成本,选Kafka。 如果你们公司够大,有专门的基础设施团队,并且需要多租户隔离,再考虑Pulsar。 不要把消息队列当成一个加分项,它在出问题的时候,是会让整个业务停摆的减分项。 记住,你的核心竞争力不是用了多先进的中间件,而是你能不能在下周一早上九点之前,把那条卡住的消息队列恢复正常。

图片