消息队列 (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
:物理集群,每个集群中可以建立多个不同的Topic
Producer
:生产者,负责将业务消息发送到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 |
---|---|---|
重启 | 需要数据复制,分钟级重启 | 重启后可直接对外服务,秒级完成 |
替换 | 需要数据复制,分钟级替换,甚至天级别 | 替换后可直接对外服务,秒级完成 |
扩容 | 需要数据复制,分钟级扩容,甚至天级别 | 扩容后可直接对外服务,秒级完成 |
缩容 | 需要数据复制,分钟级缩容,甚至天级别 | 缩容后可直接对外服务,秒级完成 |
文件结构:
在
Kafka
Partition
的基础之上,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
支持了一些高级特性:- 事务保证
- 延迟发送
- 消费重试和死信队列