消息队列原理 | 青训营笔记

119 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天

消息队列原理 | 青训营笔记

1. 消息队列

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

1.1 常用消息队列
  • Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
  • RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
  • Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计
  • BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群

2. Kafka

  1. 使用流程:创建集群——新增Topic——编写生产者逻辑——编写消费者逻辑

  2. 基本概念:

    • Topic:逻辑队列,不同Topic可以建立不同的Topic
    • Cluster:物理集群,每个集群中可以建立多个不同的Topic
    • Producer:生产者,负责将业务消息发送到Topic中
    • Consumer:消费者,负责消费Topic中的消息
    • ConsumerGroup:消费者组,不同组Consumer消费进度互不干涉
    • Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增
    • Replica:每个分片有多个Replica,Leader Replica将会从ISR(In-Sync Replicas)中选出
    • ZooKeeper:负责存储集群元信息,包括分区分配信息等
  3. Kafka消息流程:Producer——Broker——Consumer

    • Producer
      • 批量发送,减少IO次数,从而加强发送能力
      • 数据压缩,减少消息大小,目前支持Snappy、Gzip、LZ4、ZSTD压缩算法
    • Broker
      • 磁盘结构:移动磁头找到对应磁道,磁盘转动,找到对应扇区,最后写入。寻道成本比较高,因此顺序写可以减少寻道的时间成本
      • 顺序写,提高写入效率
      • 消息抓取:Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer
    • Consumer
      • Partition在Consumer Group中的分配方案
        • 手动分配(Low Level):通过手动进行分配,哪一个Consumer消费哪一个Partition完全由业务决定。缺点是不能自动容灾、会导致机器启停问题。优点是比较快。
        • 自动分配(High Level):使用Coordinator自动分配。优点是不会存在机器启停问题,分配稳定。
  4. Kafka缺点

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

3. BMQ

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

BMQ与Kafka的运维操作对比:

具体操作KafkaBMQ
重启需要数据复制,分钟级重启重启后可直接对外服务,秒级完成
替换需要数据复制,分钟级替换,甚至天级别替换后可直接对外服务,秒级完成
扩容需要数据复制,分钟级扩容,甚至天级别扩容后可直接对外服务,秒级完成
缩容需要数据复制,分钟级缩容,甚至天级别缩容后可直接对外服务,秒级完成

4. RocketMQ

RocketMQ的高级特性:事务消息、重试和死信队列,延迟队列