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

115 阅读5分钟

消息队列原理与实战

这是我参加【第五届青训营】伴学笔记创作活动的第13天

课程目标

前世今生:消息队列发展历程 消息队列-Kafka:基本概念,架构设计,底层原理,架构缺点 消息队列-BMQ:架构设计,底层原理,Kafka比较,高级特性 消息队列-RocketMQ:架构设计,底层原理,高级特性

前世今生

思考:四个场景,如何解决

  • 系统崩溃
    • 解决方案:解耦

屏幕截图 2023-02-09 195421.png

  • 服务处理能力有限
    • 解决方案:削峰

屏幕截图 2023-02-09 195450.png

  • 链路耗时长尾
    • 解决方案:异步

屏幕截图 2023-02-09 195523.png

  • 日志如何处理

屏幕截图 2023-02-09 195556.png

什么是消息队列

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

消息队列发展历程

屏幕截图 2023-02-09 195657.png

业界消息队列对比

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

消息队列-Kafka

使用场景

屏幕截图 2023-02-09 200031.png

如何使用Kafka

  1. 创建集群
  2. 新增Topic
  3. 编写生产者逻辑
  4. 编写消费者逻辑

基本概念

屏幕截图 2023-02-09 201918.png

  • Topic :逻辑队列,不同 Topic 可以建立不同的 Topic 
  • Cluster :物理集群,每个集群中可以建立多个不同的 Topic 
  • Producer :生产者,负责将业务消息发送到 Topic 中
  • Consumer :消费者,负责消费 Topic 中的消息
  • ConsumerGroup :消费者组,不同组 Consumer 消费进度互不干涉

Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增

Replica:每个分片有多个Replica,Leader Replica将会ISR中选出

Kafka架构:

屏幕截图 2023-02-09 202249.png

  • 如果发送一条信息,等到其成功后再发一条有什么问题
    • Producer-批量发送:批量发送可以减少IO次数,从而加强发送能力
  • 如果消息量很大,网络带宽不够用,如何解决
    • Producer-数据压缩:通过压缩,减少消息大小,目前支持Snappy,Gzip,LZ4,ZSTD压缩算法

Broker-磁盘结构

移动磁头找到对应磁道,磁盘转动,找到对应扇区,最后写入。寻道成本比较高,因此顺序写可以减少寻道所带来的时间成本。

屏幕截图 2023-02-09 202640.png

末尾追加,采用顺序写的方式进行写入,以提高写入效率

Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offest处的消息,按照时间窗口和消息大小窗口发送给Consumer。

  • 寻找数据如何做到
  • Broker-偏移量索引文件:二分找到小于目标offest的最大文件
  • Broker-时间戳索引文件:二分找到小于目标时间戳最大的索引位置,再通过寻找offest的方式找到最终数据

Broker-传统数据拷贝

屏幕截图 2023-02-09 203013.png

Broker-零拷贝

屏幕截图 2023-02-09 203101.png

如何解决Partition在Consumer Group中的分配问题

通过手动进行分配,哪一个Consumer消费哪一个Partition完全由业务来决定

如何帮助Kafka提高吞吐或者稳定性的功能
  • Producer:批量发送,数据压缩
  • Broker:顺序写,消息索引,零拷贝
  • Consumer:Rebalance

Kafka-重启操作

  • 关闭。重启
  • Leader切换,追赶数据
  • 数据同步完成
  • Leader回切

Kafka-问题总结

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

消息队列-BMQ

简介

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

屏幕截图 2023-02-09 203858.png

运维操作对比

屏幕截图 2023-02-09 203941.png

BMQ-高级特性

屏幕截图 2023-02-09 213737.png

泳道消息

开发流程
  1. 开发
  2. BOE
  3. PPE
  4. Prod

BOE:是一套完全独立的线下机房环境 PPE:产品预览环境

屏幕截图 2023-02-09 213837.png 多个人同时测试,需要等待上一个人测试完成

屏幕截图 2023-02-09 213850.png 每多一个测试人员,都需要重新搭建一个相同配置的Topic,造成人力和资源的浪费

屏幕截图 2023-02-09 213905.png 对于PPE的消费者来说,资源没有生产环境多,所以无法承受生产环境的流量

屏幕截图 2023-02-09 213929.png 解决主干泳道流量隔离问题以及泳道资源重复创建问题

直接使用原生SDK会有什么问题
  • 客户端配置较为复杂
  • 不支持动态配置,更改配置需要停掉服务
  • 对于latency不是很敏感的业务,batch效果不佳

Databus

屏幕截图 2023-02-09 214012.png

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

Mirror

使用Mirror通过最终一致的方式,解决跨Region读写问题

lndex

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

Parquet

  • Apache Parquet 是 Hadoop 生态圈中一种新型列式存储格式,它可以兼容 Hadoop 生态圈中大多数计算框架( Hadoop 、 Spark 等),被多种查询引擎支持( Hive 、 Impala 、 Drill 等)。
  • 直接在BMQ中将数据结构化,通过Parquet Engine,可以使用不同的方式构建Partquet格式文件

消息队列-RocketMQ

基本概念

屏幕截图 2023-02-09 204349.png

高级特性-事务场景

屏幕截图 2023-02-09 220225.png

高级特性-事务消息

屏幕截图 2023-02-09 220250.png

高级特性-延迟发送

屏幕截图 2023-02-09 220307.png

高级特性-延迟消息

屏幕截图 2023-02-09 220325.png

高级特性-处理失败

屏幕截图 2023-02-09 220429.png

高级特性-消费重试和死信队列

屏幕截图 2023-02-09 220343.png

总结

本节课让我了解了消息队列的前世和三种常见的消息队列,知道了息队列是解耦、削峰、异步、日志处理