这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
引子
常见问题处理方式
- 系统崩溃:使用消息队列解耦可能崩溃的服务
- 服务处理能力有限:使用消息队列削峰
- 链路耗时长尾:使用消息队列异步处理业务流程
- 日志如何处理:写入消息队列
前世今生
业内消息队列对比
- Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
- RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
- Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计
- BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
Kafka
使用范围
- 离线日志分析处理
- Metrics(程序状态)采集处理
- 用户行为分析
使用方法
- 创建集群
- 新增 Topic
- 编写生产者逻辑
- 编写消费者逻辑
基本概念
- Partition:分区
- Offset:消息在 Partition 内的相对位置,可以理解为唯一ID,严格递增
- Replica:副本。每个分片有多个 Replica,Leader Replica 将会从 ISR(In-Sync Replica) 中选出
- Broker-Controller:集群大脑,分配集群中的副本与Broker
- ZooKeeper:负责储存集群元信息,包括分区分配信息等
消息处理流程:Producer 生产-> Broker 消费-> Consumer
Producer-批量发送
- 批量发送减少IO次数,提高吞吐
Producer-数据压缩
- 通过压缩,减少消息大小
Broker 消息文件结构
Broker-顺序写
- 以顺序写&末尾追加的方式遵循磁盘寻道规律,提高写入效率
Broker-偏移量索引文件
- 二分找到小于目标 offset 的最大文件
Broker-时间戳索引文件
- 二分找到小于目标时间戳的最大索引位置,再通过寻找 offset 的方式找到最终数据
Broker-零拷贝
Consumer-手动分配(Low Level)
- 通过手动进行分配,哪一个 Consumer 消费哪一个 Partition 完全由业务来决定
Consumer-自动分配(High Level)
- 在 Consumer 集群中选取一个作为 Coordinator(协调者),进行自动分配管理
问题
- 重启:数据追赶操作费时、逐台重启
- 替换、扩容、缩容:数据追赶操作费时
- 负载不均衡:Broker IO 负载高,需要迁移其中部分 Partition,但迁移过程会使 IO 负载升高,运维成本高
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖 Page Cache
- Controller 和 Coordinator 和 Broker 在同一进程中,大量 I0 会造成其性能下降
BMQ
架构模型
兼容 Kafka 协议,存算分离,云原生消息队列
读写流程
HDFS 写文件流程
- 随机选取一定数量的 DataNode 写入,避免单一 Segment 负载过高
Broker-Partition 状态机
- 保证对于任意分片在同一时刻只能在一个 Broker 上存活
Broker-写文件流程
Broker-Proxy读取流程
- Wait 设置等待时间,降低 Consumer 过多时的请求频率
多机房部署
高级特性
泳道消息
- 开发流程:开发 -> BOE(完全独立的线下机房环境) -> PPE(产品预览环境) -> Prod+
- 每多一个测试人员,都要重新搭建一个相同配置的 Topic,造成人力和资源的浪费
- 对于PPE的消费者来说,资源没有生产环境多,所以无法承受生产环境的流量
- 泳道 Topic 可以解决主干泳道流量隔离问题以及泳道资源重复创建问题
Databus
- 原生 SDK 存在的问题
- 客户端配置较为复杂
- 不支持动态配置,更改配置需要停掉服务
- 对于 latency 不是很敏感的业务,batch 效果不佳
- Databus 优点
- 简化消息队列客户端复杂度
- 解耦业务与 Topic
- 缓解集群压力,提高吞吐
Mirror
- 使用 Mirror 通过最终一致性,解决跨 Region 读写问题
- Producer -> BMQ(s) -> Mirror -> BMQ(s) -> Consumer
Index
- 支持通过业务字段读取数据
- 直接在 BMQ 中将数据结构化,配置索引 DDL,异步构建索引后,通过 Index Query 服务读出数据
Parquet
- Apache Parquet 是 Hadoop 生态圈中一种新型列式存储格式,它可以兼容 Hadoop 生态圈中大多数计算框架(Hadoop、Spark等), 被多种查询引擎支持(Hive、Impala、 Dril等)
- 直接在 BMQ 中将数据结构化,通过 Parquet Engine,可以使用不同的方式构建 Parquet 格式文件
RocketMQ
使用场景:一般针对电商业务线,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等
消息转递流程
架构
存储模型
高级特性
最终一致性
延迟发送
- 可以用消息队列实现部分定时器功能(延迟发送等
消费重置和死信队列