这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记
案例一:系统崩溃
如果此时记录存储程序所在的机房被删库跑路了,上面这个流程会发生什么问题?
案例二 服务能力有限
面对庞大的请求量,处理订单的服务一脸茫然 ,它的命运该何去何从?
案例三: 链路耗时长尾
对于这个流程应该怎么优化来挽回这个暴躁的用户?
案例四:日志存储
如何解决
案例一:
解耦
案例二:
削峰
案例三:
异步
案例四:
日志处理
消息队列
什么是消息队列
消息队列(MQ),指保存消息的一个容器,本质是个队列,但这个队列呢,需要支持高吞吐,高井发,并且高可用。
业界消息队列对比
消息队列 - Kafka
使用场景
使用Kafka
基本概念
- Topic :逻辑队列,不同Topic可以建立不同的Topic
- Cluster :物理集群,每个集群中可以建立多个不同的Topic
- Producer :生产者。负责将业务消息发送到Topic中
- Consumer :消费者,负责消费Topic中的消息
- ConsumerGroup :消费者组,不同组Consumer消费进度互不干涉
Offset
Offset :消息在partition内的相对位置信息,可以理解为唯一ID , 在partition 内部严格递增。
Replica
每个分片有多个Replica,Leader Replica将会从ISR中选出。
数据复制
Kafka架构
ZooKeeper :负责存储集群元信息,包括分区分配信息等
一条消息的自述
从一条消息的视角,看看为什么Kafka能支撑这么高的吞吐?
Producer - 批量发送
思考题:如果消息量很大,网络带宽不够用,如何解决?
Prodicer - 数据压缩
Broker - 数据的存储
Broker 消息文件结构
Broker - 磁盘结构
移动磁头找到对应磁道,磁盘转动,找到对应扇区,最后写入。寻道成本比较高,因此顺序写可以减少寻道所带来的时间成本。
Broler - 顺序写
采用顺序写的方式进行写入,以提高写入效率
Broker - 如何找到消息
Consumer通过发送FetchRequest请求消息数据, Broker会将指定Offset处的消息,按照时间窗]和消息、大小窗发送给Consumer ,寻找数据这个细节是如何做到的呢?
Broker 偏移量索引文件
目标:寻找offset= 28
二分找到小于目标offset的最大文件。
Broker 时间戳索引文件
二分找到小于目标时间戳最大的索引位置,在通过寻找offset的方式找到最终数据。
Broker - 传统数据拷贝
Broker - 零拷贝
Comsumer - 消息的接收端
Consumer - Low Level
通过手动进行分配,哪一个Consumer消费哪一个 Partition完全由业务来决定。
Consumer - High Level
Rebalance
Consumer Rebalance
总结
- Producer :批量发送、数据压缩
- Broker :顺序写,消息索引,零拷贝
- Consumer : Rebalance
Kafka - 数据复制问题
Kafka - 重启操作
Kafka - 替换、扩容、缩容
Kafka - 负载不均衡
Kafka - 问题总结
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖Page Cache
- Controller 和Coordinator和Broker在同一进程中,大量I0会造成其性能下降
消息队列
BMQ简介
兼容Kafka 协议,存算分离,云原生消息队列
BMQ介绍
运维操作对比
HDFS写文件流程
BMQ文件结构
Broker - Partition 状态机
保证对于任意分片在同一时刻只能在一个 Broker上存活
Broker - 写文件流程
Broker - 写文件 Failover
Proxy
多机房部署
BMQ - 高级特性
泳道消息
- BOE: Bytedance Offline Environment,是一套完全独立的线 下机房环境
- PPE: Product Preview Environment ,即产品预览环境
多个人同时测试,需要等待上一个人测试完成
每多一个测试人员,都需要重新搭建个相同配置的 Topic ,造成人力和资源的浪费。
对于PPE的消费者来说,资源没有生产环境多, 所以无法承受生产环境的流量。
解决主干泳道流量隔离问题以及泳道资源重复创建问题。
Databus
直接使用原生SDK会有什么问题?
- 客户端配置较为复杂
- 不支持动态配置,更改配置需要停掉服务
- 对于latency不是很敏感的业务,batch效果不佳
- 简化消息队列客户端复杂度
- 解耦业务与Topic
- 缓解集群压力,提高吞吐
Mirror
使用Mirror通过最终一致的方式 ,解决跨Region读写问题。
Index
如果希望通过写入的Logld、UserId 或者其他的业务字段进行消息的查询,应该怎么做?
直接在BMQ中将数据结构化,配置索引DDL,异步构建索引后,通过Index Query服务读出数据。
Parquet
Apache Parquet是Hadoop生态圈中一种新型列式存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Hadoop、Spark等) ,被多种查询引擎支持(Hive、Impala. Drill等)
直接在BMQ中将数据结构化,通过Parquet Engine ,可以使用不同的方式构建Parquet格式文件。
小结
- BMQ的架构模型(解决Kafka存在的问题)
- BMQ读写流程( Failover 机制,写入状态机)
- BMQ高级特性(泳道、Databus、 Mirror、 Index、 Parquet )
消息队列 - RocketMQ
使用场景
例如针对电商业务线 ,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等
RocketMQ 基本概念
RocketMQ 架构
存储模型
RocketMQ - 高级特性
事务场景
延迟发送
延迟消息
处理失败
消费重试和死信队列
。