消息队列 (MQ,Message Queue),指保存消息的一个容器,本质是个队列。但是这个队列,需要支持高吞吐,高并发,并且高可用。
走进消息队列
01 消息队列前世今生
1.1 什么是消息队列
消息队列 (MQ,Message Queue),指保存消息的一个容器,本质是个队列。但是这个队列,需要支持高吞吐,高并发,并且高可用。

1.2 消息队列发展历程
- 消息队列从上个世纪九十年代就出现了。
- 1993年,IBM 开发了自己的商业消息队列
IBM MQ/WebSphere - 1997年,微软发布了
MSMQ
- 1993年,IBM 开发了自己的商业消息队列
- 然后在二十世纪初,消息队列有了更进一步的发展。
- 2001年,Sun 开发了针对 Java 语言的
JMS,本质上是一套 Java API - 2004年,发布了 MQ 规范
AMQP,同年RabbitMQ面世 - 2010年,开源了
Kafka - 2011年,阿里中间件团队自研了
RocketMQ - 2012年,Yahoo 开发了
Pulsar
- 2001年,Sun 开发了针对 Java 语言的
1.3 业界消息队列对比
Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
02 消息队列Kafka
- 主要用于离线的消息处理,如日志信息、Metrics数据、用户行为。
2.1 如何使用Kafka
- 创建集群
- 新增
Topic - 编写生产者逻辑
- 编写消费者逻辑
2.2 基本概念
Kafka的工作流程如下:
其中:
Topic:逻辑队列,不同Topic可以建立不同的Topic对象Partition:Topic的分区,不同的分区的消息可以并发处理Cluster:物理集群,每个集群中可以建立多个不同的TopicProducer:生产者,负责将业务消息发送到Topic中Consumer:消费者,负责消费Topic中的消息ConsumerGroup:消费者组,不同组的Consumer消费进度互不千涉
对于
Topic内部:
Offset:消息在Partition内的相对位置信息,可以理解为唯一 ID,在Partition内部严格递增。
对于
Partition内部:
- 每个
Partition都有多个Replica,Leader Replica将会从ISR中选出。- 如果
Leader Replica所在的机器发生宕机,那就可以从ISR中重新挑选一个Replica成为Leader Replica,以保证业务的正常运行。
- 如果
- 每个
2.3 Kafka架构
2.2 节已经说过,每个
Partition都有多个Replica,而且这些Replica并不是保存在同一台机器上的。如下图所示,Broker Controller会通过计算来确定将Topic的Partition及其副本都保存在哪些Broker上。
然后在这些
Broker的上层,有ZooKeeper来负责存储集群元信息,包括分区分配信息等。
2.4 Kafka提高吞吐和稳定性的措施
- 从
Producer方面:批量发送、数据压缩 - 从
Broker方面:顺序写,消息索引,零拷贝 - 从
Consumer方面:Rebalance
2.5 Kafka的不足之处
- 运维成本高;
- 对于负载不均衡的场景,解决方案复杂;
- 没有自己的缓存,完全依赖 Page Cache;
Controller和Coordinator和Broker在同一进程中,大量lO会造成其性能下降。
03 消息队列BMQ
BMQ兼容了Kafka协议,存算分离,云原生消息队列。
3.1 BMQ架构
由于
BMQ兼容了Kafka协议,所以它的架构与Kafka类似:
3.2 BMQ和Kafka对比
- 运维对比:
| 具体操作 | Kafka | BMQ |
|---|---|---|
| 重启 | 需要数据复制,分钟级重启 | 重启后可直接对外服务,秒级完成 |
| 替换 | 需要数据复制,分钟级替换,甚至天级别 | 替换后可直接对外服务,秒级完成 |
| 扩容 | 需要数据复制,分钟级扩容,甚至天级别 | 扩容后可直接对外服务,秒级完成 |
| 缩容 | 需要数据复制,分钟级缩容,甚至天级别 | 缩容后可直接对外服务,秒级完成 |
文件结构:

在
KafkaPartition的基础之上,BMQ还将Partition分为多个Segment,然后部署在不同的数据节点上。
3.3 BMQ高级特性
除了消息队列基本的操作之外,
BMQ还支持许多高级特性:泳道消息:用于解决主干泳道流量隔离问题以及泳道资源重复创建问题。
Databus:用于简化消息队列客户端复杂度、解耦业务与
Topic、缓解集群压力,提高吞吐。Mirror:使用
Mirror通过最终一致的方式,解决跨 Region 读写问题。Index:在
BMQ中将数据结构化,配置索引 DDL,异步构建索引后,通过 Index Query 服务读出数据。Parquet:
Apache Parquet是Hadoop生态圈中一种新型列式存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Hadoop、Sprk等),被多种查询引擎支持(Hive、Impala、Drill等)。直接在
BMQ中将数据结构化,通过Parquet Engine,可以使用不同的方式构建Parquet格式文件。
04 RocketMQ
4.1 使用场景
- 针对电商业务线,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等。
4.2 RocketMQ和Kafka对比
| 名称 | Kafka | RocketMQ |
|---|---|---|
| 逻辑队列 | Topic | Topic |
| 消息体 | Message | Message |
| 标签 | 无 | Tag |
| 分区 | Partition | ConsumerQueue |
| 生产者 | Producer | Producer |
| 生产者集群 | 无 | Producer Group |
| 消费者 | Consumer | Consumer |
| 消费者集群 | Consumer Group | Consumer Group |
| 集群控制器 | Controller | Nameserver |
4.3 RocketMQ架构

4.4 RocketMQ高级特性
RocketMQ支持了一些高级特性:- 事务保证
- 延迟发送
- 消费重试和死信队列