消息中间件的选型
吞吐量
- kafka最高,磁盘操作,因为有顺序读写、页缓存等优化
- RocketMQ 其次,磁盘操作,也有顺序读写、页缓存等,但是索引是密集索引,因此磁盘操作更多
- QMQ第三
- RabbitMQ最少,因为是内存储存
这里吞吐量需要注意,当kafka的topic太多时,会影响到它的吞吐量,但是对于RocketMQ 就没有这个问题,kafka可能数百个topic就会有性能问题,但是RocketMQ 可以有更多的topic的数量。
kafka有性能问题的原因是:
- 大量topic,Zookeeper需要有大量的watch线程维护元数据,成为瓶颈。
- 磁盘随机 I/O 增加:大量 Topic 导致日志文件分散,磁盘磁头频繁寻道(尤其是机械硬盘),破坏 Kafka 依赖的顺序写入优势。
- 分区与文件句柄:kafka的每个分区可能会打开多个文件句柄,topic太多,分区太多,可能会导致文件句柄数量超出操作系统限制。
- 页缓存(Page Cache)污染:Kafka 依赖操作系统的页缓存加速消息读写,但 Topic 过多时,不同 Topic 的数据竞争有限的缓存空间。
原因是:
- RocketMQ管理者NameServer是个轻量级的,但是kafka是用Zookeeper来管理各topic以及分区,更加重量级,因此元数据的管理压力更大。
- RocketMQ 单个 Topic 的队列数(Queue) 类似于 Kafka 的分区(Partition),但 RocketMQ 的 CommitLog是全局唯一,也就是多个topic共享一个CommitLog,因此RocketMQ 所消耗的文件句柄数只有kafka的一半(kafka是log和index文件都有),并且写入CommitLog也没有磁盘随机 I/O的问题。
延迟
- RabbitMQ最快,因为是内存操作
- RocketMQ 其次,因为是顺序追加commitLog,单条消息是5到20ms,同步副本的话是在20~100m之间
- kafka第三,因为有多个partition,因此有竞争IO的问题。单条是10到50ms,同步副本的话是在50到200ms
- QMQ第四
一致性
- RocketMQ 强一致性和最终一致性可选
- RabbitMQ强一致性
- kafka最终一致性
- QMQ最终一致性
延迟消息
- RocketMQ 支持,但是不支持随机时间的,只支持固定时间片的
- kafka不支持,需要自行实现,用时间轮算法等
- RabbitMQ 支持,利用死信队列实现
- QMQ支持,用时间轮算法实现的随机时间
事务消息
- RocketMQ 支持,类似于两阶段提交
- QMQ支持,类似于两阶段提交
- kafka不支持,kafka支持事务,但是不支持事务消息
- RabbitMQ 不支持
学习曲线与社区支持
- Kafka:学习曲线陡峭,但社区活跃,大数据生态完善
- RocketMQ:中文文档丰富,阿里系支持,适合国内团队
- RabbitMQ:入门简单,社区成熟,企业应用案例多
运维复杂度
- Kafka:高,需调优大量参数,依赖Zookeeper
- RocketMQ:中,NameServer轻量,自带管理工具
- RabbitMQ:低,开箱即用,管理界面完善
适用场景分析
kafka
- 大数据日志处理:日志收集、监控数据聚合
- 流式处理:与Flink/Spark Streaming等流处理框架集成
- 高吞吐场景:活动跟踪、消息广播
- 事件溯源:需要完整事件历史的系统
- commit log:分布式系统的持久化日志
RocketMQ 最佳场景
- 金融交易:需要高可靠性和事务支持
- 顺序消息:如订单状态变更流程
- 大规模异步解耦:电商订单系统
- 定时/延迟消息:如订单超时取消
- 分布式事务:最终一致性场景
RabbitMQ 最佳场景
- 企业级应用集成:需要多种协议支持
- 复杂路由:需要灵活的消息路由规则
- 低延迟场景:实时通知系统
- 轻量级消息队列:中小规模应用
- 快速原型开发:自带完善管理界面