消息队列|青训营笔记

70 阅读5分钟

t013e12fe7ea3baac21.jpg

这是我参与[第五届青训营]伴学笔记创作活动的第 12 天


问题提出:四个场景,如何解决?

  • 系统崩溃
  • 服务处理能力有限
  • 链路耗时长尾
  • 日志如何处理

解决方案:解耦、削峰、异步、日志处理

消息队列

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

发展历程

image.png

业界消息队列对比

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

Kafka

使用场景

  • 日志信息
  • Metrics数据,程序运行中对程序状态的采集
  • 用户行为( 搜索、点赞、评论、收藏 )

如何使用

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

基本概念

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

image.png

基本概念-Offset

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

一个Topic有多个分区Partition

image.png

基本概念-Replica

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

partition里有多个副本,副本包含不同角色,分布在集群当中不同的机器上,以达到容灾的效果

Leader进行对外的写入和读取,消费

Follwer不断从Leader拉取数据,争取保持一致,如果与Leader的差距过大会被踢出ISR

image.png

数据复制

Broker:节点,所有节点组成集群

Controller:对集群中的所有副本以及节点进行分配

image.png

Kafka架构

ZooKeeper:与controller配合

image.png

Producer

Batch处理:批量发送可以减少IO次数,从而加强发送能力,提高吞吐量

数据压缩:(网络带宽不足)通过压缩,减少消息大小,目前支持Snappy、Gzip、LZ4、ZSTD压缩算法

Broker数据的存储

Broker-消息文件结构

image.png

Broker-磁盘结构

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

image.png

Broker-顺序写

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

Broker-如何找到消息

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

寻找数据这个细节是如何做到的呢?

  • 偏移量索引文件:二分找到小于目标 offset 的最大索引位置
  • 时间戳索引文件:二分找到小于目标时间戳最大的索引位置,再通过寻找 offset的方式找到最终数据
Broker一零拷贝

image.png

Consumer一消息的接收端

image.png

Consumer-Low Level

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

缺点:当一个consumer挂掉,对应的partition流就失效了(不能自动容灾);新增consumer时,需要停机重新分配

优点:快

Consumer-High Level

每个 Cunsumer group使用一个Coordinator自动分配(Rebalance

Kafka存在的问题

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

BMQ

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

image.png

HDFS写文件流程

随机选择一定数量的DataNode进行写入

Broker-Partition状态机

保证对于任意分片在同一时刻只能在一个 Broker上存活

image.png

BMQ-高级特性

image.png

泳道消息

BOE: Bytedance Offline Environment,是一套完全独立的线下机房环境

PPE: Product Preview Environment,即产品预览环境

image.png

解决主干泳道流量隔离问题以及泳道资源重复创建问题

下游的消费者只会消费其所在泳道的生产者的信息

image.png

Databus

直接使用原生SDK会有什么问题?

  1. 客户端配置较为复杂
  2. 不支持动态配置,更改配置需要停掉服务
  3. 对于latency 不是很敏感的业务, batch效果不佳

image.png

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

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

Index

如果希望通过写入的Logld、Userld或者其他的业务字段进行消息的查询 应该怎么做?

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

Apache Parquet是Hadoop生态圈中一种新型列式存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Hadoop、Spark等),被多种查询引擎支持(Hive、Impala、Drill等)

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


RocketMQ

使用场景

例如,针对电商业务线,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等

基本概念

image.png

高级特性

事务场景、延时发送、消费重试和死信队列


参考资料

t.csdn.cn/diWFj

t.csdn.cn/UJDCv