消息队列 | 青训营笔记

137 阅读3分钟

消息队列

本章具体包含了常见的消息队列的技术选型和基本架构与原理,重点介绍了Kafka和字节自研的BMQ,Kafka的话属于开源项目,文档和项目demo比较齐全;BMQ的话应该没有开源,应该只是字节内部使用,文档之类的比较少。

消息队列前世今生

  • 问题:1.系统崩溃;2.服务处理能力有限;3.链路耗时长尾;4.日志如何处理

  • 解决方案:1.解耦;2.削峰;3.异步;

  • 业界消息队列

    • Kafka:高吞吐
    • RocketMQ:实时
    • Pulsar:存算分离
    • BMQ:字节的,类似Pulsar

消息队列Kafka

  • 收集日志信息、Metrics数据、用户行为

  • 如何使用Kafka

    • 创建集群
    • 新增Topic
    • 编写生产者逻辑
    • 编写消费者逻辑
  • 基本概念:

    • Topic:逻辑队列
    • Cluster:物理集群;单个节点称为Broker
    • Producer:生产者
    • Consumer:消费者
    • ConsumerGroup:消费者组
    • Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增
    • Replica:每个partition有多个Replica,Leader Replica会从ISR(In-Sync Replicas)中选出
    • Controller:记录集群元数据
  • Broker消息文件结构

    • .log
    • .index:稀疏索引
    • .timeIndex:时间戳索引
  • Broker如何找到消息

    • Consumer发送FetchRequest,Broker会根据偏移量去找索引文件再找到具体消息
  • Broker数据拷贝

    • 零拷贝sendfile系统调用
  • 如何解决Partition在ConsumerGroup中的分配问题?

    • 手动分配:代码配置;不能自动容灾、加新Consumer不方便,不够弹性
    • 自动分配:有一个Coordinator(Broker);Consumer Rebalance:选一个Consumer Leader交换信息
  • 重启、替换、扩容、缩容

  • 负载不均衡:不好解决

  • 问题总结:1.运维成本高;2.不好做负载不均衡;3.没有缓存,完全依赖page cache;4.Controller和Coordinator和Broker在同一进程,大量IO影响性能

消息队列BMQ

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

image-20230521211256521.png

运维更简单,更快

底层是HDFS

Broker-Partition状态机

image-20230521211613420.png

Broker写文件流程

image-20230523213514526.png

这里的ACK机制类比Kafka

failover机制:重新找一个DataNode而不是一直等待

Proxy机制:会先wait(防止消费者一直轮询),再在cache中找数据,没有的话去磁盘找

多机房部署

高级特性:

image-20230523214831033.png

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

  • Databus:简化配置,支持动态配置;分为Databus Server和Databus Agent,适合大吞吐

image-20230523215533626.png

  • Mirror:跨Region读写,最终一致,双方视角都是在本机房处理的消息。如果只是通过多机房会很高延迟;

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

  • Parquet:Hadoop中一种新型列式存储,兼容大多数计算框架(Hadoop、Spark),被多种查询引擎支持(Hive、Impala、Drill);在BMQ中结构化,以便支持后续的大数据框架

image-20230523214931462.png

多个人同时测试需要等上一个,每个人创建一套环境也很浪费,PPE验证也扛不住线上流量

消息队列RocketMQ

低延时,实时业务