消息队列 | 青训营笔记

95 阅读4分钟

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

作用

应用场景

  • 异步
  • 削峰
  • 解耦
  • 消息通讯

常用

  • Kafka
  • RocketMQ
  • Pulsar
  • BMQ

Kafka

使用场景

  • 搜索服务
  • 直播服务
  • 订单服务
  • 支付服务

使用流程

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

ZooKeeper

负责集群元数据的管理、控制器的选举等

基本概念

  • Topic 逻辑队列
  • Cluster 物理集群
  • Producer 生产者
  • Consumer 消费者
  • ConsumerGroup 消费者组,每一个分区只能被一个消费组中的一个消费者所消费

Topic

一个消息中间件可能由多个队列,生产者和消费者需要知道处理那个队列,给队列取名字,Topic,不同Topic可以建立不同的Topic

  • Broker 一台Kafa服务器
  • partition 对Topic的分区(存储上可以看作是一个可追加的日志文件),提高topic的吞吐量,实际上的partition会分布在不同的broker中
  • offset 消息在partition内的位置,消息被追加到分区日志文件的时候都会分配一个特定的offset,offset是消息在分区中的唯一标识,Kafka用它保证消息在分区内的顺序性
  • Replica 每个分片有多个Replica 副本,分区中所有副本称为AR,所有与leader副本保持一定程度同步的副本组成ISR(包括leader),与leader副本同步滞后过多的副本OSR
  • HW 高水位,标识了一个特定的消息offset,消费者只能拉取到这个offset之前的消息
  • LEO 标识当前日志文件中吓一跳待写入消息的offset,分区ISR中每个副本会维护自身的LEO,ISR中最小的LEO即为分区的HW

Broker 传统数据拷贝

磁盘空间->内核空间->应用空间

磁盘->Read Buffer->Application Buffer->Socket Buffer->NIC Buffer->消费者进程

Borker 零拷贝

磁盘->Read Buffer->NIC Buffer->消费者进程

consumer

消息接收端

解决partition在consumer中的分配:

  • 手动分配,由业务决定;缺点:consumer挂掉,新建consumer困难
  • 自动分配 High Level,由一个协调者coordinator

Consumer Rebalance

帮助自动分配

高可用-分布式分区出问题?ISR

一个Topic中的数据在不同partition上,kafka会把这些partition做备份(分布于不同的broker中)。

partition分为主分区和备份分区,主分区用于读写,备份分区只做备份,若主分区Broker挂了,那么会选举其他的Broker来作为主分区,实现高可用。

为何能支持高吞吐

  • Producer:批量发送可以减小IO;数据压缩,通过压缩,减少消息大小,目前支持:Snappy、Gzip、LZ4、ZSTD
  • Broker:顺序写,减小磁盘的寻道时间,零拷贝
  • 偏移量索引文件 二分查找
  • 时间戳索引文件 在offset层加一层二级索引

消费者分区分配策略

RangeAssignor、roundrobinAssigntor、StickyAssignor

存储视图

图源:juejin.cn/post/714613… image.png

缺点

  • 系统复杂性高
  • 数据一致性:分布式服务的问题,但是消息队列使这个问题暴露更严重,可用分布式事务解
  • 可用性:中间件MQ可能会挂
  • 运维成本高
  • 对于负载不均衡的场景,解决方案复杂
  • 没有自己的缓存,完全依赖Page Cache
  • Controller和Cooridinator和Broker在同一进程中,大量IO会造成其性能下降

重启操作

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

BMQ

兼容Kafka协议,存算分离,云原生消息队列,在重启、替换、扩缩容方面有速度优势

Broker

Partition状态机

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

写文件

先写入Buffer再写入磁盘

写文件Failover

写文件失败:...

泳道Topic

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

Databus

  • 配置简单(相比于SDK)
  • 支持动态配置,更改配置不需要停服务

Mirror

通过最终一致的方式,解决跨域读写问题

Index

Parquet

RocketMQ

基于低延时场景,实时业务使用较多

  • Tag
  • ConsumerQueue:分区