(十六)走进消息队列 | 青训营笔记

179 阅读6分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记

前言

1 系统崩溃

解决方案:解耦。

用消息队列在存储服务前收发消息,存储服务从消息队列里获取请求。储存服务崩溃,消息队列还能够收发消息,不会影响业务。

2 服务处理能力有限

解决方案:削峰。

先将大量请求存在消息队列中,每次从消息队列获取少量请求进行处理。

3 链路耗时长尾

解决方案:异步。

4 日志如何处理

解决方:先存入消息队列里。再进行处理

什么是消息队列

保存消息的一个容器。支持高吞吐,高并发,高可用

一、消息队列的发展历程

1 发展历程

image.png

2 对比

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

二、Kafka

1 使用场景

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

2 使用方法

image.png

集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。

3 基本概念

image.png

  • Topic:逻辑队列,不同业务逻辑可以建立不同的 Topic
  • Cluster:物理集群,每个集群中可以新建不同的 Topic 处理不同的业务逻辑
  • Producer:生产者,服务将业务消息发送到 Topic中
  • Consumer:消费者,负责消费 Topic 中的消息
  • ConsumerGroup:消费者组,不同组的 Consumer 消费进度互不影响
  • Broker 缓存代理,Kafka集群中的一台或多台服务器统称broker

3.1 Offset(相对位置)

  • Offset(相对位置):消息在 partition 内的小队位置信息,可以理解为唯一ID,在 partition 内部严格递增
  • partition(分区):Topic 分区,消息并发处理,提高单个Topic处理能力。

image.png

3.2 Replica(副本)

image.png

  • Replica:每个分片有多个 Replica,Leader Replica 将会从 ISR 中选出。
    • Follower从Leader中拉取数据,差距过大提出 ISR 。Leader如果宕机,从Follower里面选出一个当Leader。

4 数据复制

Controller控制Topic-Partition在Broker上的分配 image.png

5 Kafka架构

image.png

  • Zookeeper:与Controller配合,负责存储一些集群的元数据信息、分区的一些分配信息等,Controller计算好的方案都会放在这个地方。

6 一条信息的自述

image.png 从一条消息的角度,看看为什么Kafka能支撑这么高的吞吐?

6.1 Producer

6.1.1 批量发送

如果对于 Producer 如果发送一条消息等待成功后再发送下一条,处理能力太小。 image.png 支持批量处理,加强发送能力。

6.1.2 数据压缩

如果单个大小很大,消息量很大,带宽不够用怎么办。 image.png 通过压缩,减小消息大小,支持Snappy,Gzip,LZ4,ZSTD压缩算法。默认Snappy,ZSTD比较好。

6.2 Broker

6.2.1 消息文件结构

image.png

6.2.2 磁盘结构

Broker 将文件存入磁盘中,寻道成本高。通过顺序写来提高效率,尽量不移动磁头。

6.2.3 寻找数据

Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer。 根据 offset 来寻找,二分查找小于目标 offset 的最大文件。再二分查找小于目标的最大Batch,然后在Batch中顺序查找。

image.png

image.png

6.2.4 传统数据拷贝

image.png

6.2.4 零拷贝

image.png

6.3 Consumer

image.png Consumer 收到从 Broker 发送的数据之后,Partition如何在ConsumerGroup中分配?

6.3.1 手动分配

  • 手动分配:手动分配哪一个Consumer消费哪一个Partition。

image.png 不能自动容灾,扩展机器会导致服务停止。优点是比较快。

6.3.2 自动分配

image.png

  • 自动分配:在Broker集群中,选取一台Broker为Coordinator,帮助自动分配。

6.3.3 Consumer Rebanlance

image.png

6.4 总结

  • Producer: 批量发送,数据压缩;

  • Broker:顺序写,消息索引,零拷贝;

  • Consumer:Rebalance

Kafka的问题:

  • 运维成本高 ;
  • 对于负载不均衡的场景,解决方案复杂 ;
  • 没有自己的缓存 ;
  • controller 和 coordinator 和 broker 在同一进程,大量 IO 会造成性能下降。

三、BMQ

1 简介

兼容Kafka协议,存算分离,云原生消息队列。架构图如下:

image.png

2 与Kafka的运维对比

具体操作KafkaBMQ
重启需要数据复制,分钟级重启重启后可直接对外服务,秒级完成
替换需要数据复制,分钟级替换,甚至天级别替换后可直接对外服务,秒级完成
扩容需要数据复制,分钟级扩容,甚至天级别扩容后可直接对外服务,秒级完成
缩容需要数据复制,分钟级缩容,甚至天级别缩容后可直接对外服务,秒级完成

3. HDFS 写文件流程

image.png

4. BMQ 文件结构

image.png

5. Broker-Partition 状态机

image.png

写文件流程:

image.png

数据校验,参数是否合法。校验完成后放入 Buffer 中,通过一个异步的 Writer Thread 线程将数据写入底层的储存系统之中。当文件到达一定大小是需要建一个新的segment文件。这个文件会随机挑选与副本数量相当的数据节点进行插写入,此时如果一个结点出现了问题,导致不能正常写入了。不能等着结点恢复,不知道他什么时候能恢复,应该直接将其替换掉。

image.png

Consumer 发送 Fetch Request 之后会有一个 Wait 流程。作用是,如果没有数据写入的话 Consumer 就会一直发送,请求过多服务端会出问题,因此设置了一个等待机制。如果没有 Fetch 到数据 proxy 会等待一定时间。

image.png

6. 多机房部署

image.png

7. BMQ 高级特性

image.png

8. 泳道消息

image.png

image.png

image.png

image.png

image.png

9. Databus

image.png

10. Mirror

image.png

11. Index

image.png

12. Parquet

Apache Parquet 是 Hadoop 生态圈中一种新型列式存储结构,可以兼容 Hadoop 生态圈中大多数计算框架,被多种查询引擎支持。

image.png

image.png

13. 小结

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

四、RocketMQ