消息队列|青训营笔记
这是我参与「第五届青训营」笔记创作活动的第十二天,今天学习了消息队列相关概念并了解了经典的kafka和BMQ架构
引入
- 四个场景|问题
- 系统崩溃
- 服务处理能力有限
- 链路耗时长尾
- 日志处理
解决方案
- 系统崩溃
- 解耦
- 解耦
- 处理能力优先
- 削峰
- 削峰
- 链路耗时长尾
- 异步进行
- 异步进行
- 日志处理
消息队列
定义:保存消息的一个容器,高并发,高吞吐,高可用
发展历程与由来
- 常见消息队列
- Kafka:高吞吐场景
- RocketMQ :实时场景
- Pulsar
- BMQ
Kafka
使用场景:离线的消息处理
eg:日志信息,Metrics数据,用户行为
使用:
- 创建集群
- 新增Topic
- 编写生产者逻辑
- 编写消费者逻辑
概念
- Topic:逻辑队列,不同的业务场景,不同的topic
- Partition:topic内分区可以并行处理
- Cluster:物理集群,每个集群可以建立多个topic
- Producer:生产者,将业务消息发到Topic
- Consumer:消费者
- ConsumerGroup:不同组的consumer互不干涉
topic内部
- offset:消息在partition内的相对位置,唯一ID,在partition内严格递增
- Replica partition中的副本,用于容灾
- ISR:leader在ISR选出,保证高可用
- leader:对外写入和读取
- follower:拉取leader数据,保持一致
- controller:确定partition存储
架构
消息的流转
producer-批量发送
- Producer将消息打包一起发送,减少IO次数
- 同时为了减少带宽要求需要进行压缩处理
- 常用压缩算法:snappy,Gzip,ZSTD
Broker--数据存储
- 消息文件结构
- .log真实日志
- .index offset的映射
- .timeindex时间映射
- 磁盘结构
- 磁头,盘片....
- 顺序写,减少寻道次数
- 找到消息
- Consumer 发送请求消息(FetchRequest)->Broker 将指定Offset的信息->Consumer
- 偏移量索引文件
- 时间戳索引文件
- 时间戳->offset->数据
- 数据拷贝
- 传统型拷贝
- 零拷贝
- 传统型拷贝
Consumer--消息接收
- 问题:Partition在Consumer Group中的分配 consumer应该拉取哪一个partition?
- 解决方式
- 手动分配:完全由业务决定
- 缺点:
- 若consumer崩掉,无法自动容灾
- 无法动态调整consumer的作用
- 缺点:
- 自动分配(High-Level)
- 利用一个BROKER作为Coordinator(协调者),动态分配
- 过程(Consumer Rebalance)
- 找到coordinator
- 向coordinator发送加入请求
- coordinator选拔leader
- 同步集群分配方案
- 心跳,确认是否死掉
- 找到coordinator
- 手动分配:完全由业务决定
缺点
数据复制问题
- 重启操作
- 回切:避免最终leader集中在一个broker上
- 替换,扩容,缩容
- 替换:相比重启需要追更多数据
- 扩容:都存在数据复制问题
- 缩容:都存在数据复制问题
负载不均衡
- 当某一个partition数据较大时,可能出现负载不均衡的 情况
- 降低负载,迁出其余partition,引入了新的io问题
BMQ
- 特点:
- 兼容kafka协议,producer和consumer
- 存算分离:broker上存储的数据单独利用文件系统存储
- 架构
- Controller和coordinaror独立部署
- proxy cluster
- 读取直接由proxy向分布式系统读取,且不需要数据复制
- 写操作则不做处理直接传给Broker Cluster
由于不需要数据复制
HDFS写文件
- 随机选择一定数量的DataNode写入
- 负载均衡解决
- partition打散随机分配
Broker-Partition状态机
- controller分配方案->Broker->Broker Recover【争夺写入权限,并保证数据一致】->save checkpoint-> create segment ->appaend data
Broker
写文件流程
写文件Failover
- 若DataNode 节点挂了或者其他原因导致写入失败:换一个节点写入
读文件(proxy)
- wait :设置时间和文件大小窗口,避免频繁的请求
- Cache:
- 命中->return data
- 未命中->storage->openfile->seek->read
多机房部署
高级特性
泳道消息
- 问题:
- 多个人同时测试
- 串行时间太长
-并行每个建个topic成本太高
- 串行时间太长
- 多个人同时测试
- 泳道:每个topic附带一个泳道topic
- 测试时 不同泳道消费者只会消费本身泳道生产的消息
- 消息不经线上
Databus
- 引入:
- 原生SDK
- 客户端配置复杂
- 不支持动态配置,更改配置需要停掉服务
- 对于latency不是很敏感的业务,batch效果不佳
- 结构
- Agent 打包发给BMQ
- server 及时更新配置
- 优点
- 简化消息队列客户端复杂度
- 解耦业务与topic
- 缓解集群压力,增大吞吐量
Mirror
Index
希望通过Logid和Userid或其他字段查询
- 一般方式
- offset
- timesamp
Parquet
标题:消息队列前世今生 - 掘金