当前位置: 首页 > news >正文

Apache 消息队列分布式架构与原理

消息队列

基本概念

定义

消息队列(Message Queue, MQ)是一种分布式中间件,通过异步通信、消息暂存和解耦生产消费双方的机制,提供消息的顺序性保证、可靠投递和流量控制能力,广泛应用于微服务解耦、大数据流处理等场景。

核心组件

生产者 producer:消息的生产者,负责发送消息。

消费者 consumer:消息的消费者,订阅并处理消息。

消费者组 consumer group:所有消费者都属于某一消费者组,同一个消费者组内的消费者共同消费同一类型的消息,实现消费性能的扩展。

租户 tenant:逻辑概念,是资源归属和权限控制的基本单位。

集群 cluster:一组节点的集合。

Broker:用于存储和转发消息的物理节点。

主题 topic:逻辑概念,同一种业务类型的消息的集合。

偏移量 offset:消息的唯一标识,由消费者返回,记录目前消费的位置。

消息模型

点对点:消息被单个消费者消费,如订单处理。

发布/订阅:消息广播给多个消费者,如新闻推送。

核心功能

功能

说明

服务解耦

解除多个业务系统之间的耦合度,减少系统之间影响

异步通信

生产者和消费者无需同时在线,通过消息队列暂存消息实现异步通信

流量控制

削峰填谷,突发流量被队列缓冲,避免压垮下游系统

顺序收发

先进先出,保证消息的顺序性(全局有序或分区有序)

零拷贝

通过 OS 和硬件协作,减少数据在内存中的冗余复制,实现高吞吐

消息回溯

 offset 到指定位置,重新消费历史消息

应用场景

大数据流处理:实时数据处理 ETL

金融支付对账、交易流水

物联网设备指令下发、状态上报

微服务:服务 A 通过 MQ 通知服务 B,避免直接 HTTP 调用带来的耦合和超时风险

Kafka

架构设计

1.  生产者从 ZooKeeper* 获取 Topic 的元数据(如 Partition Leader 的位置)后,以 push 模式发布消息到对应的 broker 上。

2.  每条消息都属于一个 Topic,每个 Topic 分为多个 Partition 分区,物理上由多个日志分片 Segment 文件组成。每个 Partition 都有多个副本,被存储在不同的 Brokers 上。消息发送到 Leader 后,会同步到 Follower 以确保冗余。

3.  消费者以 pull 模式从 Leader 主副本里拉取消息,返回 offset 值用于记录现在消费的位置。

* ZooKeeper 的核心作用

功能

说明

Broker 注册

Broker 启动时向 ZooKeeper 注册自己的地址和 Partition 分配情况

Leader 选举

当 Leader Partition 宕机时,协助选举新的 Leader

Topic 配置管理

存储 Topic 的 Partition 数量、副本因子等元数据

功能原理

1.  持久化:消息存储在 broker 磁盘中,被消费后不会立即被删除

2.  高吞吐:单个 partition 批处理,多个 partition 并行处理

3.  高扩展:topic 分区化,存储在不同 brokers 中

4.  容灾和高可用:每个 partition 都有多个副本,ISR 确保副本之间的同步

5.  低延迟:稀疏索引和二分查找

RocketMQ

架构设计

1.  生产者向 NameServer 查询 Topic 的路由信息,选择目标 MessageQueue。

2.  发送消息到对应的 Master Broker,同步到 Slave。

3.  消费者从 NameServer 获取 Topic 的路由信息,从 Master Broker 拉取消息,定期提交 Offset 到 Broker。

功能原理

1.  金融级可靠

同步刷盘

所有消息先写入磁盘后才返回 ACK,确保数据不丢失

主从同步复制

消息必须同步到 Slave 节点后才响应生产者,避免主节点宕机丢数据

Broker 主从切换

Master 故障时,Slave 自动提升为新 Master

多副本

支持多副本,数据分布在不同物理机/机架

严格的顺序性

同一队列的消息严格 FIFO,适用于金融交易(如订单状态变更)

死信队列

处理失败的消息自动进入 DLQ,避免阻塞正常流程

2.  事务消息:两阶段提交

生产者发送一条对消费者不可见的半消息(Half Message)到 Broker,Broker 持久化该消息,但不会将其投递给消费者。

生产者执行本地数据库操作后,根据本地事务结果,向 Broker 发送 Commit 或 Rollback 指令。

仅当收到 Commit 后,Broker 才将消息标记为可消费,后续推送给消费者,以确保本地数据库事务和消息发送两个操作的原子性。

3.  消息过滤:基于 tag 或 sql 语句进行过滤,在服务端将符合条件的消息投递给消费者。

Pulsar

产品架构设计

* Segment 即 BookKeeper 的 Ledger,是一种 append-only 的日志文件

1.  生产者查询 Topic 路由,将消息发送到对应的 Broker

2.  消息被拆分为多个 Segment,broker 将消息写到多个 bookie 中持久化存储同一个 partition 的 segment 分散在多个 bookie,支持多个 bookie 并行读取。

3.  消费者请求消息,broker 从 bookie 中拉取消息并转发给消费者

功能原理

1.  计算(Broker)与存储(Bookie)分离:

- broker:无状态的 proxy 服务,负责接收消息、传递消息、集群负载均衡等操作。

bookie:有状态,负责持久化存储消息

2.  故障隔离:Broker 崩溃不影响数据,Bookie 故障自动从其他副本重建恢复。

3.  弹性扩展:Broker 无需考虑数据迁移,可快速水平扩缩容;Bookie 存储层可按需独立扩展,新增 Bookie 后,数据自动重新分布。

MQ 系列对比

产品

Kafka

RocketMQ

Pulsar

产品特性

高并发、高吞吐、实时流处理平台

低延迟、高可靠、强一致

云原生、存算分离、跨地域复制

应用场景

对吞吐要求高的离线场景

对可靠性要求高的在线业务场景

兼容在线和离线请求

适用业务

网页活动追踪

日志分析、监控采集

流数据集成

电商在线支付、直播

证券交易

金融对账

跨云/跨地域数据同步

IoT 设备管理监控

Serverless 事件驱动

broker

存储数据,处理消息请求

存储数据,处理消息请求

无状态的服务,不存储数据,只负责消息的路由处理

数据存储单位

Partition

CommitLog(唯一物理存储文件,完全顺序写入)

Segment(颗粒更小,更利于存储负载均衡)

数据一致性

依赖 ISR 机制

同步刷盘 + 主从同步

BookKeeper 支持同步复制

扩展性

通过增加 Partition 数量,扩容 Broker 需要 rebalance

通过增加 Broker 组扩展 Queue 数量

Broker/Bookie 独立按需扩展计算/存储

故障切换

依赖 Controller 选举新 Leader

组内 Slave 接管 Master无需数据迁移立即接管

Broker 崩溃后,新节点无需数据迁移立即接管

Bookie 节点故障时,数据自动从其他副本重建

常见问题

为什么需要消息队列?

首先知道什么消息队列消息队列通过解耦生产消费者实现消息异步流量控制功能

那么什么生产者/消费者生产者通常是业务动作的发起者生产需要被传递或处理的业务数据可以是订单系统支付系统传感器设备消费者通常下游服务数据分析模块比如库存系统Spark 作业

为什么需要解耦生产者消费者消息队列产品的主要作用就是转储日志、监控数据等,举个例子就像丰巢快递柜,快递员若是不能把快递及时送到人员手上会造成快递拥堵,效率减慢;但是有丰巢柜来存储后就可以有一个地方暂存,消费者需要消费的时候再去拿快递,拉消息一样的道理。通过消息队列,业务系统可以做到故障隔离(生产者宕机不影响消费者)弹性扩展(应对流量波动),真正实现“高内聚、低耦合”的业务架构。

为什么叫消息队列为集群?

集群是一组节点的集合,节点可以是物理机或虚拟机。消息队列产品采用了分布式架构设计通过多节点协作实现高可用高性能扩展性具体参见上面架构设计

命名空间是做什么的?

命名空间多租户之间实现逻辑隔离。

首先要理解多租户的概念,多租户就是多个用户共享一个集群。消息队列产品通过命名空间角色权限配合实现权限管控从而实现不同命名空间逻辑隔离具体来讲就是用户角色配置某个命名空间读写权限一个命名空间里的所有 topic 都继承相同的设置则用户只对该命名空间内的 topic 操作权限可以参考下图帮助理解

如何理解 topic 这个概念?

学习消息队列产品过程中注意区分逻辑概念和物理概念 topic partition 都是业务逻辑概念实际上最后消息都是一个 segment 文件形式存储物理机器

topic 代表了消息的类别或主题,是生产消费的最小单位。从业务层面来讲,topic 就像是一个消息的分类标签,生产者将相关的消息发送到特定的 topic 中,而消费者则通过订阅感兴趣的 topic 来获取和处理这些消息。这种设计使得不同业务领域的消息能够自然地隔离,比如订单系统的消息可以发布到"order_topic",而支付系统的消息则流向"payment_topic",从而实现业务逻辑的清晰划分。

topic 的设计还体现了消息队列的关键特性——发布/订阅模式。生产者不需要知道有哪些消费者存在,只需关注将消息发送到正确的 topic;同样,消费者也只需订阅自己关心的 topic,无需感知消息的生产者是谁。这种松耦合的架构使得系统各组件能够独立演化,大大提升了整体架构的灵活性。此外,通过 topic 可以实现消息的多播,即一条消息可以被多个消费者组同时消费,这在需要将同一数据用于不同业务场景时显得尤为重要。

什么是数据落盘?

计算机存储内存缓存

消息队列接收到的数据写入磁盘持久化存储过程叫做落盘比如消息存储 kafka rocketmq broker 以及 pulsar bookie 磁盘这个过程

具体实现kafka 消息先写入 Page Cache(内存缓冲),再异步刷盘(可配置同步刷盘)RocketMQ 支持同步刷盘(每条消息立即写入磁盘)或异步刷盘(批量写入)

消息队列如何保证数据的一致性?

kafka 通过 ISR(In-Sync Replicas)机制来维护数据一致性。当生产者发送消息时,Leader 副本会先将消息写入本地日志,然后要求所有 ISR 中的 Follower 副本完成同步复制后,这条消息才会被确认为已提交。

RocketMQ 采用了双重保障机制来维护数据一致性。首先是同步刷盘策略,当 Broker 接收到消息后,可以选择立即将消息写入磁盘(同步刷盘)而非仅保留在内存中。其次是主从同步机制,每个主节点都会将消息同步到其从节点,只有当主从都成功写入后才会向生产者返回确认响应。

Pulsar 依赖 BookKeeper 作为底层存储引擎,每条消息都会被同步复制到多个 Bookie 节点,只有当大多数节点确认写入后,这条消息才会被标记为持久化成功。

参考链接

Apache Kafka

RocketMQ · 官方网站 | RocketMQ 消息队列

Apache Pulsar | Apache Pulsar

https://zhuanlan.zhihu.com/p/103249714

http://www.dtcms.com/a/296635.html

相关文章:

  • 六种经典智能优化算法(PSO/GWO/WOA/HHO/DBO/SSA)无人机(UAV)三维路径规划,Matlab代码实现
  • 【三桥君】大语言模型计算成本高,MoE如何有效降低成本?
  • Java学习---Spring及其衍生(下)
  • Oracle 时间处理函数和操作符笔记
  • 数据库常用DDL语言
  • 洛谷 P1996 约瑟夫问题之题解
  • LLM针对隐藏层的特征增强的相关论文
  • Python生成折线图
  • 7.24 C/C++蓝桥杯 | 排序算法
  • 外企本土化布局对国内连接器企业影响几何?
  • 排序初识(上)-- 讲解超详细
  • 【接口自动化】-1- 初识接口
  • VUE的学习
  • shell编程
  • 加密算法-----BCrypt
  • C语言第四章函数
  • Java八大基本类型
  • ICCV 2025 | CWNet: Causal Wavelet Network for Low-Light Image Enhancement
  • 视频剪辑软件使用到的技术栈详解
  • 教育培训系统源码技术拆解:前后端分离、企业培训课程推送机制全解析
  • act_hi_taskinst表历史任务记录不同步,无数据
  • LeetCode 刷题【12. 整数转罗马数字】
  • 解决VSCode无法加载Json架构问题
  • uniapp vue3版本中使用pinia 以及持久化处理 以及在微信小程序ypeError: Cannot read property ‘localStorage‘ of undefined报错
  • 车机版凤凰FM:纯净无广告,免费畅享海量有声资源
  • vue3使用异步加载腾讯地图
  • 奈奎斯特定理与香农公式在说些什么?
  • Linux系统下使用apt下载系统组件对应版本的源码
  • 训练日志7.23
  • k8s常用命令介绍