BMQ 消息队列系统|青训营笔记

172 阅读5分钟

青训营笔记|BMQ信息队列系统

前提引入

问题:

  1. 删库跑路。系统崩溃
  2. 服务处理能力有限
  3. 服务连服耗时长
  4. 日志如何处理

结局方法

  1. 引入信息队列,解耦。
  2. 引入信息队列,削峰。
  3. 引入信息队列,异步处理。
  4. 引入信息队列,日志处理。

概念

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

业界消息队列

  1. Kafka
  2. RocketMQ
  3. Pulsar
  4. BMQ

BMQ

简介

BMQ 兼容Kafka 协议,存算分离,云原生信息队列,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的 Kafka 集群。

基本概念

  • Topic:逻辑队列,业务场景-topic
  • Cluster:物理集群,集群中可以新建多个不同的 topic
  • Producer:生产端,发送业务信息到 topic 中
  • Consumer:消费端,消费已经发送到 topic 中的信息
  • Partition:topic 中有多个分片,不同分片信息可以并发处理。
  • Offset:消息在 partition 内的相对位置,唯一 ID。
  • Replica::分片的副本,每个分片有多个 Replica,其中 Leader 对外服务,Follower 同步 Leader 数据(副本)。
  • ISP:同步中的副本,在 ISP 中的副本可以提升为 Leader
  • Broker:Kafka 的节点,所有的 Broker 节点组成一个集群。
  • Controller:负责对副本和 Broker 进行分配
  • ZooKeeper:集群的基础上,模块,这个模块储存了集群的元数据信息,包括分区分配信息等。

Producer

  • 批量发送
  • 数据压缩

Broker数据存储

image.png

  • Topic
    • Partition
      • Replica
        • Log
          • LogSegment
            • .log(日志文件)
            • .index
            • .timeindex
            • 其他文件

顺序写入

Broker 数据查找

  1. offset 索引,二分找到小于目标 offset 的最大索引位置,再遍历找到目标 offset
  2. 若是时间戳索引,通过二分找到时间戳对应的 offset 重复以上步骤

Broker传统数据拷贝与零拷贝

详情见 ppt

Consumer 与 Partition 分配问题

  • 手动分配(Low Level)
  • 自动分配(High Level)

在 Broker 集群中,对于 Consumer Group 来讲,选取 一台 Broker 作为 coordinator,coordinator 帮助 Consumer Group 进行分片的分配(rebalance)

image.png

BMQ架构图

image.png

Producer->Consumer->Proxy->Broker->HDFS->Controller->Coordinator->Meta

Kafka 与 BMQ 的运维操作对比

BMQ 相对于 Kafka 不需要进行数据复制,进行操作后可直接对外服务。

HDFS写文件流程

随机选择一定数量的 DataNote 进行写入,DateNote 数量是副本数,一个副本由多个 segment 组成,对于单个副本的所有 segment来说,随机分配到分布式文件系统的整个集群中。

BMQ 文件结构

相比于 Kafka 通过现在 Leader 上写入数据,再同步到 follower 上,容易造成负载不均衡的问题。

但在 BMQ 集群中,对于单个副本来说,是随机分配在不同的节点上面的。

image.png

Broker-Partition状态机

状态机机制:保证对于任意分片在同一时刻只能在一个 Broker 上存活。

首先,Controller 做好分片的分配,分配到Broker,Start 分片,进入 Recover 状态。在 Recover 状态中分为两种,一种是获取分片的写入权利,对于 HDFS 而言,只允许一个分片写入,第二种是如果分片异常中断,再进行一次 Save checkpoint。进入正常的写流程状态,创建文件,写入数据。

Broker-写文件流程

Messages->数据检验->Buffer->Write Thread->Storage

其中 Write Thread 线程将数据最终写入到底层的存储系统中,先将 Buffer 中的数据取出来,调用底层写入逻辑,在一定的时间周期进行 flush,flush 后建立 index,即 offset 和 timestamp 对于消息具体位置的映射关系,当 index 建立后,save checkpoint,若 flush 完成后宕机,index 还未建立,数据不被消费。当文件到达一定大小是,需要建立一个新的 segment 文件写入。

Broker-写文件 Failover

当 DateNode 节点挂了,重新找正常的节点创建新的文件进行写入

Proxy

Fetch Request->wait->Cache->Storage

Consumer发送 Fetch Request,设置等待机制 wait 降低 IO 次数,先去 Cache 中寻找数据,若无则去存储系统寻找,若找到该文件进行以下操作:打开文件,通过 index 寻找数据所在具体位置,从这个位置开始读取数据。

多机房部署

对于高可用服务,防止单机故障带来的影响外,还要防止机房级故障带来的影响。Proxy->Broker->Meta->HDFS

BMQ-高级特性

  1. 泳道
  2. Databus
  3. Mirror
  4. Index
  5. Parquet

泳道信息

开发->BOE->PPE->Prod

问题:对于测试人员,若重新搭建相同配置的 Topic 会造成浪费,或对于 PPE 的消费者来说,资源没有生产环境多,无法承受流量

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

Databus

问题场景:

使用原生 SDK 客户端配置复杂,不支持动态配置,更改配置需要停掉服务,对于 latency 不是敏感的业务,batch 效果不佳

Datebus作用:

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

image.png

Mirror

解决跨 Region 读写

Index

解决通过其他业务字段进行信息的查询

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

parquet

Parquet 是一种新型列式存储格式,兼容大多数计算框架,被多种查询引擎支持。

行式存储:方便进行查询

列式存储:方便大数据分析

总结

  1. BMQ 架构模型(解决 Kafka 存在的问题)
  2. BMQ 读写流程(Failover 机制,写入状态机)
  3. BMQ 高级特性(泳道,Databus,Mirror,Index,Parquet)