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

mq是如何实现的

一、MQ 的本质与边界

MQ(消息队列)本质是:用持久化日志 + 路由与订阅,在生产者与消费者之间实现解耦、削峰填谷、异步化与弹性并发
边界:

  • 不是数据库(复杂事务/二级索引能力有限);
  • 不是RPC(时延约束与失败模型不同);
  • “分布式日志 + 分发系统”,支持回放、扩展与容错

核心目标函数:在吞吐(Throughput)延迟(Latency)一致性/可靠性(Consistency/Reliability)、**可扩展性(Scalability)**之间做权衡。


二、总体框架(抽象参考架构)

           ┌──────────────┐
Producer → │  Ingress层   │  ← batch / compression / acks└──────┬───────┘│┌───────▼────────┐│  路由与订阅层   │  ← topic/partition、订阅组、路由表└───────┬────────┘│┌────────▼─────────┐│   存储与复制层    │  ← Append-only WAL、段文件、稀疏索引、复制└────────┬─────────┘│┌──────▼───────┐
Consumer ← │  出站传输层  │  ← pull/push、flow control、ack、重试/DLQ└──────────────┘

关键数据结构

  • Topic / Queue:逻辑通道;Topic 多用于 pub/sub,Queue 偏点对点。
  • Partition/Shard:最小并行与存储单元;决定扩展与顺序边界。
  • Offset/Sequence:单分片内单调递增位点。
  • Consumer Group:竞争消费语义(同组内一条消息只给一个成员)。

三、内部关键机制(深入但通俗)

3.1 存储:Append-only + 段文件 + 稀疏索引

  • 顺序写磁盘是吞吐的根:利用页缓存、预读/预写,避免随机 IO。
  • 段切分(segment):如 1GB/段,便于清理与回收;段内再按 Record 批组织。
  • 稀疏索引:每 N 条或每 N 字节建索引,定位近似,再顺序扫。
  • 保留与清理:按时间/大小;**压实(compaction)**可按 Key 保留最后一条,降低存储与重放成本。
  • 页式缓存与零拷贝:mmap / sendfile 减少用户态↔内核态拷贝。

3.2 路由与订阅

  • 主题分片:一致性哈希或固定分区;按 Key 分区可保序与热点隔离。
  • 路由表:在 Broker 或 Metadata 服务中维护(如 Kafka KRaft、Pulsar/ZK + BK、RocketMQ NameServer)。
  • 订阅模式:exclusive(排他)、shared/queue(组内竞争)、failover(主备)、fanout(各拿一份)、key_shared(同 key 单消费者且保序)。

3.3 传输与流控

  • Push / Pull:Push 延迟更低、需要背压;Pull 可控性更强。
  • 信用流控(credit/窗口):消费者声明 N,Broker 仅下发 N 条未 ACK;ACK 返还配额。
  • 批量(batching):入站/出站都做批;批量 + 压缩(lz4/zstd)=吞吐器。
  • ACK 与重试:At-least-once 下,未 ACK 超时重投;多次失败入 DLQ

3.4 投递语义与精确一次

  • At-most-once:可能丢,不重试,时延最低。
  • At-least-once:可能重;配合幂等(去重键、状态机)即可满足绝大多数业务。
  • Exactly-once:系统级昂贵(事务日志/两阶段提交/读写隔离等),推荐用业务幂等 + Outbox/Inbox落地:
    • Outbox:业务写库与“待发表”同事务;由异步转发器保证至少一次送达 MQ;
    • Inbox:消费端以业务唯一键去重并原子提交业务状态与消费位点。

3.5 高可用与复制

  • Leader/Follower 复制:ISR、复制延迟监控;acks=all 提升可靠性。
  • 共识协议:Raft(RabbitMQ Quorum Queue、Pulsar BK ledger)、KRaft(Kafka)。
  • 跨机房/跨地域:镜像/异步复制、多活;权衡写入延迟 vs 容灾等级。

3.6 顺序与重平衡

  • 顺序边界:仅保证单分区内顺序;跨分区无全局有序。
  • 重平衡(rebalance):组成员变更/分区迁移;要限流并保证在位点边界切换,减少重复或丢失。

四、三大优势的工程实现

4.1 多连接(海量长连)

  • 连接复用:一条 TCP 上开多逻辑通道(Channel);减少 FD 与上下文切换。
  • 事件驱动网络栈:epoll/kqueue/IOCP(Netty、Tokio/Erlang);单机支撑数十万连接。
  • 轻量状态:连接会话放在 slab/arena;心跳 + 空闲回收;限速与拒绝服务阈值。
  • 操作系统调优ulimit -nsomaxconn、端口范围、rmem/wmem、TIME_WAIT 策略;容器内同样需要。

4.2 高吞吐

  • 追加写 + 大段文件:最小化随机 IO;顺序读写最大化磁盘/SSD 带宽。
  • 批量 + 压缩:Producer linger.ms(例如 210ms)等待聚合;`batch.size`(32128KB);压缩 lz4/zstd。
  • 分片并行:分区数按 CPU × 2~3 起步;对热点 Key 做 hash+盐。
  • 零/少拷贝:mmap/sendfile、内存池、共享缓冲区;减少 GC 和复制。
  • 后台作业限流:rebalance/compaction/索引重建必须限速,避免前台时延抖动。

4.3 低延迟

  • 小批量/小 linger:优先写延迟敏感流;高吞吐场景再调大。
  • ACK/复制策略:低延迟路径用 acks=1 或异步复制;强一致路径用 acks=all + 同步副本。
  • 信用流控:消费者窗口合理(32~512);避免推爆客户端导致重传风暴。
  • 线程与队列隔离:I/O 与业务处理分离;热点分区绑定线程减少迁移。
  • 尾部延迟治理:观察 P95/P99,定位磁盘抖动、GC 停顿、系统调用长尾、锁争用、网络 buffer 不足等。

五、如何保证订阅者处理精准处理消息

两种语义,不要混淆

  1. 组内唯一处理(竞争消费):同订阅组内,一条消息只给一个成员。
    • Kafka:Consumer Group + 分区独占。
    • RabbitMQ:同队列多消费者天然竞争;严格单活可用 x-single-active-consumer
    • Pulsar:Shared/Key_Shared/Failover;Key_Shared 对相同 Key 单消费者且保序。
    • NATS JetStream:Queue Group。
  2. 每个订阅方都拿一份:Kafka 用“不同 consumer group”;RabbitMQ 用“多队列绑定”;Pulsar 用“不同 subscription name”;JetStream 用“不同 durable consumer”。

工程落地建议:默认 At-least-once + 幂等。Exactly-once 只在强需求的非常小的链路上启用(如 Kafka EOS / RocketMQ 事务)。


六、主流 MQ:架构差异与调优抓手

6.1 Kafka

  • 架构:Topic→Partition→Replica;KRaft 共识;拉取式消费。
  • 优势:高吞吐、可回放、生态(Connect/Streams/Schema Registry)。
  • 关键参数
    • Producer:acksretrieslinger.ms(2~10ms)、batch.size(64KB)、compression.type(lz4/zstd)。
    • Broker:num.network.threadsnum.io.threadssocket.send/receive.buffer.byteslog.segment.byteslog.retention.*message.max.bytes
    • Consumer:max.poll.recordsfetch.min.bytesfetch.max.wait.mssession.timeout.msenable.auto.commit(通常关)、max.partition.fetch.bytes
  • 实务
    • 分区数按并发规划;按 Key 分区保序。
    • 重平衡频繁 → 增大 session.timeout/max.poll.interval 并优化消费者处理时间。
    • 长期保留结合 compaction;Mirror/Replicator 做跨地域。

6.2 RabbitMQ

  • 架构:Exchange→Queue 路由,推送 + ack;Quorum Queue(Raft)替代镜像队列。
  • 优势:路由灵活、多协议(AMQP/MQTT/STOMP)、管理控制台好用。
  • 关键参数
    • prefetch(Qos)、publisher confirmsx-single-active-consumerx-queue-type=quorumx-queue-mode=lazy(磁盘优先)。
  • 实务
    • 大堆积不建议(更适 Kafka/Pulsar);
    • 复杂路由(topic/headers)要留意匹配开销;
    • 延迟/定时消息用插件或 TTL+DLX 组合。

6.3 RocketMQ

  • 架构:NameServer + Broker;commitlog + consume queue 索引;拉/推混合。
  • 优势:事务消息(半消息+回查)、延迟消息(多级)、顺序消息。
  • 关键参数:刷盘(同步/异步)、复制(同步/异步)、堆外内存与映射文件大小、发送批量。
  • 实务
    • 金融/订单强一致链路;
    • 顺序消息需绑定队列;
    • 延迟等级策略要与业务重试对齐。

6.4 Pulsar

  • 架构:Broker 无状态 + BookKeeper(ledger);原生多租户、Geo-Replication、分层存储(S3/OSS)。
  • 优势:云原生、长保留与回放、Key_Shared 保序与并行折中。
  • 关键参数receiverQueueSize、订阅模式、ledger 大小、backlog 阈值、tiered storage 开关。
  • 实务
    • BookKeeper 的磁盘/网络对吞吐与时延影响显著;
    • 分层存储可大幅降低成本;
    • 多租户隔离(配额/限流)务必开启。

6.5 NATS JetStream

  • 架构:极简协议 + 内存优先;JetStream 增强持久化(Stream/Consumer)。
  • 优势:极低延迟、部署简单、适合微服务控制面/IoT。
  • 关键参数AckPolicyMaxAckPendingDeliverPolicyReplicasMaxMsgs/MaxBytes
  • 实务
    • 与传统 MQ 思维不同,更像“轻量流系统”;
    • 控制面事件/命令最合适;
    • 大堆积与复杂回放不如 Kafka/Pulsar。

七、工程实践与避坑

  1. 幂等与去重
  • 生产端 Outbox,消费端基于业务唯一键/去重表;幂等更新(UPSERT/ON CONFLICT DO NOTHING)。
  1. 重试与死信(DLQ)
  • 固定 + 指数退避;区分可恢复/不可恢复;不可恢复直接 DLQ 并告警。
  1. 背压与限流
  • 生产端令牌桶或漏桶;消费端窗口;Broker 侧当 shard/backlog 超阈时限流,防抖。
  1. 可观测性
  • 指标:入/出吞吐、P95/99 延迟、Backlog 深度、重平衡次数、ISR/复制延迟、ACK 超时、DLQ 速率、压缩比。
  • 日志:结构化、采样长尾;链路追踪(traceId)串起一次消息的全生命周期。
  1. 数据生命周期
  • 保留策略与成本核算;冷热分层(Pulsar)或 compact(Kafka)。
  1. 安全
  • 认证/鉴权(SASL/OAuth/JWT/Token)、TLS、Topic/Namespace 级 ACL、配额(连接/带宽/消息数)。
  1. 变更与演练
  • 分区扩容/重均衡做灰度与限流;
  • 故障演练:Broker 崩溃、网络分区、磁盘满、消费者雪崩、重试风暴。

八、选型与容量规划清单

8.1 快速选型(场景→工具)

  • 行为日志/实时数仓/可回放:Kafka(或需要多租户/分层→Pulsar)。
  • 复杂路由/多协议/任务分发:RabbitMQ/ActiveMQ Artemis。
  • 金融订单/事务/延迟/顺序:RocketMQ。
  • 超低延迟控制面/IoT:NATS JetStream。

8.2 容量估算(起步公式)

  • 吞吐
    • 写入带宽 ≈ msg_size × qps × 压缩比⁻¹
    • 分区数 ≈ 目标并发消费者数(或 CPU×(2~3) 起步,压测校正)。
  • 存储
    • 日存储 ≈ 写入带宽 × 86400 × 保留天数
    • Kafka compact 主题:有效容量 ≈ 活跃 key 数 × 平均 value 大小 × 副本数 × overhead
  • 副本与可用性
    • R=3(本地多 AZ)常见;跨地域镜像异步。
    • 强一致路径需评估同步复制对 P99 的抬升。

8.3 调参起点(可根据业务微调)

  • Kafka Producerlinger.ms=2~10msbatch.size=64KBcompression=zstdacks=all|1
  • Kafka Consumermax.poll.records=500fetch.min.bytes=1~64KB、禁用自动提交,批量处理后提交。
  • RabbitMQprefetch=100~500publisher confirms 开启、队列选 quorum,单活需求→x-single-active-consumer
  • PulsarreceiverQueueSize=100~1000,按延迟 vs 吞吐调;订阅模式选 Key_Shared 兼顾保序与并行。
  • NATS JetStreamMaxAckPending=200~1000AckPolicy=Explicit,拉/推按业务选。

结语(带走三句话)

  1. 吞吐靠顺序写 + 批量 + 压缩 + 分片并行
  2. 低延迟靠小批量 + 合理 ACK/复制策略 + 信用流控 + 尾部延迟治理
  3. 消息被订阅者精准消费,靠订阅组语义(竞争消费/排他)+ 业务幂等
http://www.dtcms.com/a/398756.html

相关文章:

  • 【区间贪心】P3661 [USACO17FEB] Why Did the Cow Cross the Road I S|普及+
  • AIGC实战——BicycleGAN详解与实现
  • 基于Element Plus的Vue3远程搜索多选组件实现与优化
  • 网站只做静态页面安全受到影响南昌旅游集团网站建设
  • pom.xml 不在根目录,idea无法识别项目处理方案
  • 网站开发所需硬件昆明微网站搭建
  • 【第25话:路径规划】自动驾驶路径规划概念与理论介绍
  • QT多窗口跳转
  • 栈(Stack)
  • 整体设计 逻辑全链 之8 受控的自然语言-字面拼凑:正则表达式 之2
  • 攻防世界-Web-simple_php
  • 【Linux我做主】进程程序替换和exec函数族
  • 清华最新发布 | 大型推理模型的强化学习综述
  • C++异常处理的根本缺陷:隐式传播的性能陷阱与控制流断裂
  • 【东枫】USRP X310 母版 PCB
  • 山东锦华建设集团有限公司网站嘉瑞建设有限公司网站
  • 食品品牌网站策划美容行业培训网站建设
  • Amazon Timestream新用户实时分析:从零到上手完整指南
  • 淘宝联盟个人网站怎么做电商平台入驻
  • 在 Oracle SQL 中实现 `IF-ELSE` 逻辑 SQL 错误 [12704] [72000]: ORA-12704: 字符集不匹配
  • 勒索软件专攻数据库弱点:Oracle 服务器安全防线告急
  • 常用的表空间维护语句
  • MySQL笔记---数据库基础
  • 【数据迁移】:oracle 大数据上线失败复盘:【大表定义变更】不一致导致生产数据灌入失败及解决方案
  • InnoDB一致性读与锁定读全解析
  • Oracle归档及数据库存储空间查询
  • 怎么用wordpress建外贸网站华丽的网站模板
  • 如何在Linux系统里将新添加磁盘进行分区挂载
  • 公司网站案例免费域名建站
  • 抓包解析MCP协议:基于JSON-RPC的MCP host与MCP server的交互