这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记
前言
1 系统崩溃
解决方案:解耦。
用消息队列在存储服务前收发消息,存储服务从消息队列里获取请求。储存服务崩溃,消息队列还能够收发消息,不会影响业务。
2 服务处理能力有限
解决方案:削峰。
先将大量请求存在消息队列中,每次从消息队列获取少量请求进行处理。
3 链路耗时长尾
解决方案:异步。
4 日志如何处理
解决方:先存入消息队列里。再进行处理
什么是消息队列
保存消息的一个容器。支持高吞吐,高并发,高可用。
一、消息队列的发展历程
1 发展历程
2 对比
| 名称 | 特点 |
|---|---|
| Kafka | 分布式的、多区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色 |
| RocketMQ | 低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景重运用较广 |
| Pulsar | 是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计 |
| BMQ | 和Pulsar架构类似,存算芬利,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群 |
二、Kafka
1 使用场景
- 日志信息
- Metrics数据
- 用户行为
2 使用方法
集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。
3 基本概念
- Topic:逻辑队列,不同业务逻辑可以建立不同的 Topic
- Cluster:物理集群,每个集群中可以新建不同的 Topic 处理不同的业务逻辑
- Producer:生产者,服务将业务消息发送到 Topic中
- Consumer:消费者,负责消费 Topic 中的消息
- ConsumerGroup:消费者组,不同组的 Consumer 消费进度互不影响
- Broker 缓存代理,Kafka集群中的一台或多台服务器统称broker
3.1 Offset(相对位置)
- Offset(相对位置):消息在 partition 内的小队位置信息,可以理解为唯一ID,在 partition 内部严格递增
- partition(分区):Topic 分区,消息并发处理,提高单个Topic处理能力。
3.2 Replica(副本)
- Replica:每个分片有多个 Replica,Leader Replica 将会从 ISR 中选出。
- Follower从Leader中拉取数据,差距过大提出 ISR 。Leader如果宕机,从Follower里面选出一个当Leader。
4 数据复制
Controller控制Topic-Partition在Broker上的分配
5 Kafka架构
- Zookeeper:与Controller配合,负责存储一些集群的元数据信息、分区的一些分配信息等,Controller计算好的方案都会放在这个地方。
6 一条信息的自述
从一条消息的角度,看看为什么Kafka能支撑这么高的吞吐?
6.1 Producer
6.1.1 批量发送
如果对于 Producer 如果发送一条消息等待成功后再发送下一条,处理能力太小。
支持批量处理,加强发送能力。
6.1.2 数据压缩
如果单个大小很大,消息量很大,带宽不够用怎么办。
通过压缩,减小消息大小,支持Snappy,Gzip,LZ4,ZSTD压缩算法。默认Snappy,ZSTD比较好。
6.2 Broker
6.2.1 消息文件结构
6.2.2 磁盘结构
Broker 将文件存入磁盘中,寻道成本高。通过顺序写来提高效率,尽量不移动磁头。
6.2.3 寻找数据
Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer。 根据 offset 来寻找,二分查找小于目标 offset 的最大文件。再二分查找小于目标的最大Batch,然后在Batch中顺序查找。
6.2.4 传统数据拷贝
6.2.4 零拷贝
6.3 Consumer
Consumer 收到从 Broker 发送的数据之后,Partition如何在ConsumerGroup中分配?
6.3.1 手动分配
- 手动分配:手动分配哪一个Consumer消费哪一个Partition。
不能自动容灾,扩展机器会导致服务停止。优点是比较快。
6.3.2 自动分配
- 自动分配:在Broker集群中,选取一台Broker为Coordinator,帮助自动分配。
6.3.3 Consumer Rebanlance
6.4 总结
-
Producer: 批量发送,数据压缩;
-
Broker:顺序写,消息索引,零拷贝;
-
Consumer:Rebalance。
Kafka的问题:
- 运维成本高 ;
- 对于负载不均衡的场景,解决方案复杂 ;
- 没有自己的缓存 ;
- controller 和 coordinator 和 broker 在同一进程,大量 IO 会造成性能下降。
三、BMQ
1 简介
兼容Kafka协议,存算分离,云原生消息队列。架构图如下:
2 与Kafka的运维对比
| 具体操作 | Kafka | BMQ |
|---|---|---|
| 重启 | 需要数据复制,分钟级重启 | 重启后可直接对外服务,秒级完成 |
| 替换 | 需要数据复制,分钟级替换,甚至天级别 | 替换后可直接对外服务,秒级完成 |
| 扩容 | 需要数据复制,分钟级扩容,甚至天级别 | 扩容后可直接对外服务,秒级完成 |
| 缩容 | 需要数据复制,分钟级缩容,甚至天级别 | 缩容后可直接对外服务,秒级完成 |
3. HDFS 写文件流程
4. BMQ 文件结构
5. Broker-Partition 状态机
写文件流程:
数据校验,参数是否合法。校验完成后放入 Buffer 中,通过一个异步的 Writer Thread 线程将数据写入底层的储存系统之中。当文件到达一定大小是需要建一个新的segment文件。这个文件会随机挑选与副本数量相当的数据节点进行插写入,此时如果一个结点出现了问题,导致不能正常写入了。不能等着结点恢复,不知道他什么时候能恢复,应该直接将其替换掉。
Consumer 发送 Fetch Request 之后会有一个 Wait 流程。作用是,如果没有数据写入的话 Consumer 就会一直发送,请求过多服务端会出问题,因此设置了一个等待机制。如果没有 Fetch 到数据 proxy 会等待一定时间。
6. 多机房部署
7. BMQ 高级特性
8. 泳道消息
9. Databus
10. Mirror
11. Index
12. Parquet
Apache Parquet 是 Hadoop 生态圈中一种新型列式存储结构,可以兼容 Hadoop 生态圈中大多数计算框架,被多种查询引擎支持。
13. 小结
- BMQ 的架构模型(解决 Kafka 存在的问题)
- BMQ 读写流程(Failover 机制,写入状态机)
- BMQ 高级特性(泳道、Databus、Mirror、Index、Parquet)