消息队列详解

149 阅读4分钟

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

消息队列

一、什么是消息队列

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

消息队列的使用场景

  • 系统奔溃:业务中的某个部分的服务器被删库跑路,导致调用接口失败

    应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败

    image-20230209112843439

  • 服务处理能力有限:数据量超越服务器所能承载的最大量

    限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况

    image-20230209112902957

  • 链路耗时长尾:业务流程过于冗长,导致服务器处理时间过长

    异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间

    image-20230209112918727

  • 日志如何处理

    利用消息队列处理日志

    image-20230209112754372

二、kafka

Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据

kafka的设计目标

  1. 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能
  2. 高吞吐率,即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输
  3. 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输
  4. 同时支持离线数据处理和实时数据处理

kafka的架构

image-20230209114746049

  • Producer :消息生产者,就是向kafka broker发消息的客户端
  • Consumer :消息消费者,向kafka broker取消息的客户端
  • Topic :kafka中的逻辑队列,可以理解成每一个不同的业务场景就是一个不同的topic,对于这个业务来说,所有的数据都存储在该队列中

  • Cluster:kafka的物理集群,每个集群可以建立多个不同的topic

  • Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic

  • Partition:topic的分片,不同分片的直接消息可以通过并发来处理

  • Consumer Group (CG):一个topic可以有多个CG,不同CG的消费者互不干涉

  • Offset:kafka的存储文件都是按照offset.kafka来命名

  • Controller:集群大脑,负责对副本和Broker进行分配

  • ZooKeeper:存储集群的元数据信息

  • Replica:分片的副本,分布在不同的机器上,可以用来容灾,leader对外服务,follower异步去拉去leader的数据进行一个同步,如果leader挂了,可以将follower提升为leader再对外服务

    image-20230209115911554

kafka的数据传输

image-20230209130615780

数据一条一条的传输,当数据量足够大时,会造成相应时间过长,IO消耗也非常巨大,通过打包可以减少IO消耗,但会造成数据巨大,所以传输的是打包后压缩好的数据,这样就能承受海量数据的传输

image-20230209130312400

Broker如何找到消息

文件的存储采用的是稀疏索引的方式

偏移量索引查找

image-20230209130917376

利用二分查找找到offset小于目标文件的最大索引位置,再顺序查找

时间戳索引查找

image-20230209131029951

二分查找找到对应的时间戳,再用偏移量索引的方式查找

Consumer消息接收

LOW-LEVEL

image-20230209131345810

手动分配,启动比较快,但如果某个消费者挂了或需要新增消费者,需要停掉整个集群,重新分配后再上线

HIGH-LEVEL

image-20230209131708500

选取一个broker作为coordinator,帮助CG进行分配,这样,无论是有消费者宕机还是新增消费者,coordinator都能重新分配CG和partition

kafka问题总结

  1. 运维成本高
  2. 对于负载不均衡的场景,解决方案复杂
  3. 没有自己的缓存
  4. controller、coordinator和broker在同一进程中,大量IO会导致性能下降

三、BMQ

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

BMQ架构

image-20230209132652415

与kafka的运维操作对比

image-20230209132734509

BMQ和kafka相比,性能的提升是显著的

BMQ文件结构

image-20230209132958969

在BMQ集群中,单个副本是随机分配到不同的结点上面的,所以不会出现负载不均衡的问题

BMQ高级特性

泳道消息:

image-20230209133806148

DataBus:

  1. 简化消息队列客户端复杂度
  2. 解耦业务与Topic
  3. 缓解集群压力,提高吞吐

Mirror:

image-20230209133912226

Index:直接在BMQ中将数据结构化,配置索引DDL,异步构建索引后,通过Index Query服务读出数据

image-20230209133936388

Parquet:直接在BMQ中将数据结构化,通过Parquet Engine,可以使用不同的方式构建Parquet文件

image-20230209134016620

BMQ的读写流程

  • Failover

    image-20230209134128674

  • 状态机

    image-20230209134214115

四、RocketMQ

RocketMQ架构

image-20230209134504772

与kafka的比较

image-20230209134452814

RocketMQ高级特性

  • 事务消息

    image-20230209134657476

  • 消费重试和死信队列

    image-20230209134708537

  • 延迟队列

    image-20230209134756643