消息队列 | 青训营笔记

97 阅读2分钟

这是我参与「第三届青训营-后端场」笔记创作活动的的第15篇笔记。

场景

  • 系统崩溃 -- 解耦
  • 服务处理能力有限 -- 削峰
  • 链路耗时长尾 -- 异步
  • 日志如何处理

消息队列(MQ)指保存消息的一个容器,本质是个队列,需要支持高吞吐、高并发、高可用。

常见消息队列

Kafka

分布式的、多分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色。

使用场景

  • 日志信息
  • Metric 数据
  • 用户行为

如何使用

  • 创建集群
  • 新增Topic
  • 编写生产者逻辑
  • 编写消费者逻辑

基本概念

  • Producer:生产者,负责将业务消息发送到Topic
  • Consumer:消费者,负责消费Topic中的消息
  • ConsumerGroup:不同组 Consumer 消费进度互不干涉
  • Topic:逻辑队列,每个Topic可以有多个Partition,并发处理
  • Cluster:物理集群,每个集群可以建立多个不同的 Topic
  • Offset:消息在partition中的相对位置信息,在partition内部严格递增
  • Replica: 副本,每个partition有多个replica,分布在集群的不同机器上(容灾)
    • Leader:对外写入/读取
    • Follower:不断拉取leader数据,努力与leader保持一致
    • ISR(In-Sync Replicas):与leader差距(offset或时间)在一定范围内的follower。如果leader的机器宕机,就从ISR中选择一个follower来对外服务。
  • Broker:集群中的节点
  • Kafka架构中还会有ZooKeeper:负责存储集群元信息,包括分区分配信息等

Kafka 支撑高吞吐的方法

  • Producer:消息批量发送,数据压缩(Snappy,ZSTD等)
  • Broker:
    • 顺序写,提高写入磁盘的效率;
    • 二分找到小于目标offset的最大索引位置,或者根据时间戳先找到小于目标时间戳最大索引位置
    • 零拷贝
  • Consumer:reblance机制,通过 coordinator 为 consumer 自动分配 partition

Kafka 问题:

  • 运维成本高
  • 对于负载不均衡的场景,解决方案复杂
  • 没有自己的缓存,完全依赖 Page Cache
  • Controller 和 Coordinator 和 Broker 在同一个进程中,大量IO会造成起性能下降

BMQ

兼容Kafka协议,存算分离,云原生消息队列

  • Producer --> Proxy Cluster --> Broker Cluster --> Distributed Storage System
  • Distributed Storage System --> Proxy Cluster --> Consumer

读写流程

  • 同一个partition的所有segment不会像Kafka一样全部分布在一个节点上,而是打散分布在集群中
  • 写入状态机
  • failover

高级特性

  • 泳道消息
  • Databus
  • Mirror:解决跨 region 读写问题
  • Index
  • Parquet

RocketMQ

低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广

  • Tag
  • Nameserver
  • Producer group

高级特性

  • 事务场景
  • 延迟发送。Schedule topic
  • 消费重试和死信队列。

Pulsar

下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用存算分离的架构