【课程笔记】走进消息队列 | 青训营笔记

150 阅读5分钟

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

0、引入-消息队列

  • 案例1:系统崩溃

image.png

  • 解决方案:解耦

image.png

  • 此时,就算记录存储发生了故障或宕机,请求也会放到消息队列里面,不会引起业务的故障。
  • 案例2:服务处理能力有限

image.png

  • 解决方案:削峰

image.png

  • 案例3:链路耗时长尾 image.png

  • 解决方案:异步

image.png

  • 案例4:日志如何处理
  • 解决方案:

image.png

  • 总结:消息队列(MQ):指保存消息的一个容器,本质上是一个队列。但是这个队列需要支持,高吞吐、高并发、并且高可用

image.png

1、前世今生

image.png

  • 业界消息队列对比: image.png

2、消息队列-Kafka

2.1、使用场景:

  • 放日志信息数据
  • 放Metrics数据:采集程序运行状态数据
  • 放用户行为数据

2.2、如何使用Kafka

  1. 创建集群
  2. 新增Topic:设置分区数量
  3. 编写生产者逻辑
  4. 编写消费者逻辑

2.3、基本概念

  • Topic:逻辑队列,每一个不同的业务场景就是一个topic

  • Cluster:物理集群,每个集群可以建立多个不同的topic

  • Producer:生产者,负责将业务消息发送到Topic

  • Consumer:消费者,负责消费Topic中的消息

  • ConsumerGroup:消费组,不同组Consumer消费进度互不干涉

  • Partition:一个Topic有多个分区,可以并发执行,因此可以提高吞吐量 image.png

  • Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增(保证消息的顺序性)。

image.png

  • Replica:每个分片有多个Replica, Leader Replica将会从ISR中选出(leader负责写入读取,follower赋值leader的数据,“尽可能”保证一致以达到容灾的目的)。如果某个时刻,服务器发生了宕机,就从ISR中选择一个副本选择为一个leader,保证高可用。

image.png

2.2 数据复制

  • 图中有4个broker,代表了kafka集群中的节点
  • 图中1个broker有2个topic
  • 图中controller,集群的大脑,负责将集群中的所有副本和broker进行分配 image.png

2.5 kafka架构

  • ZooKeeper:负责存储集群的元信息,包括分区分配信息等。 image.png

2.6 一条消息的自述(看kafka工作流程)

image.png

  • Q:如果发送一条消息,等到其成功后再发一条有什么问题?
  • A: 吞吐率低(有限时间内发送的消息很少)

2.6.1、producer发送数据

image.png

  • 问题:如果消息量很大,网络带宽不够用如何解决? image.png

2.6.2、broker存储数据

image.png image.png

  • 采取顺序写(所有消息都是末尾添加),以提高写入效率: image.png image.png

2.6.3、broker寻找消息

  • 偏移量索引文件: image.png image.png image.png
  • 时间戳索引文件 image.png

2.6.4、broker继续优化

  • 传统数据拷贝:
    • 从磁盘拷贝到内核态,再拷贝到用户态,内核态才能使用到这份数据 image.png
  • Broker-零拷贝: image.png

2.6.5、Comsumer-消息的接收端

image.png

  • 手动分配(预定义好consumer的分配方式):
    • 问题1:每个consumer接受一部分partion,当一个consumer出现问题,对应partition的数据流就断掉了,不能自动容灾。
    • 问题2:consumer增加或减少的时候,不方便调度partition。
    • 好处:快 image.png
  • 自动分配
    • 由Coordinator(协调者)帮助某个consumer group的各个consumer分配partition image.png
  • 自动分配的Consumer Rebalance(略)
  1. consumer去申请一个负载最低的一个broker作为coordinator;
  2. coordinator选取一个consumer为leader(计算分配的策略);
  3. consumer发起SyncGroupRequest,同步集群上的数据;
  4. consumer在一定间隔内发起“心跳”,告诉coordinator它还正常工作中,以防止consumer发生宕机; image.png

总结:

  • 为什么kafka支持高吞吐?
  • Producer:批量发送、数据压缩;
  • Broker:顺序写,消息索引,零拷贝;
  • Consumer:Rebalance

kafka-数据复制问题(节点变动时,都会发生)

image.png

  • kafka-重启操作
    • 重启节点特别多的时候,出现负载均衡问题 image.png
  • kafka-替换、扩容、缩容

image.png

  • kafka-负载不均衡
    • 带来数据复制的问题,IO增加,成本增加

kafka-问题总结

  1. 运维成本高
  2. 对于负载不均衡的场景,解决方案复杂
  3. 没有自己的缓存,完全依赖page cache
  4. Cotroller和Coordinator和Broker在同一进程中,大量IO会造成其性能下降

3、消息队列-BMQ

  • BMQ: 兼容Kafka协议,存算分离,云原生消息队列
    • 增加了Proxy(对于写请求,proxy不做任何处理,让broker做写入;对于读请求。proxy直接对分布式存储系统读取);
    • 将Controller和Coordinator独立出来了;
    • 存算分离,在底层增加了一个分布式存储系统 image.png

3.2、运维操作对比

image.png

3.3、HDFS写文件流程

  • HDFS利用DataNode存储 image.png

3.4、BMQ文件结构

  • BMQ的一个partition的segment分配在不同节点上,Kafka分配在一个节点上 image.png

3.4、BMQ-Broker-Partition状态机

  • 目的:解决脑裂问题,保证对于任意分片在同一时刻只能在一个Broker上存活,防止乱序;

image.png

3.5、BMQ-Broker-写文件流程

image.png

3.5、BMQ-Broker-写文件failover

image.png

3.6、BMQ-proxy

  • 读取流程
    • wait:在有很多consumer的场景下,避免consumer不断发送fetch request请求 image.png

3.7、BMQ-多机房部署

  • 目的:除了防止单机故障,也要防止机房级带来的影响(比如,机房断电); image.png

3.8、BMQ-高级特性

image.png

3.9、BMQ-高级特性-泳道消息

image.png

image.png

image.png

image.png

  • 解决主干泳道流量隔离问题以及泳道资源重复创建问题。 image.png

3.10、BMQ-高级特性-Databus

image.png

image.png

3.11、BMQ-高级特性-Mirror

image.png

image.png

3.12、BMQ-高级特性-Index

  • 2种查询方案(下图右侧) image.png

3.13、BMQ-高级特性-Index

image.png

3.14、BMQ-高级特性-parquet

image.png

  • 什么是列式存储?

image.png

image.png

4、消息队列-RocketMQ

  • 使用场景

image.png

4.1、基本概念

image.png

image.png

image.png

4.2、RocketMQ架构

image.png

4.3、RocketMQ存储模型

  • 每一个broker只有一个commitlog image.png

4.4、RocketMQ高级特性-事务场景

  • 保证库存-1和订单记录+1具有事务特性(都需要成功) image.png

4.4、RocketMQ高级特性-事务消息

image.png

4.4、RocketMQ高级特性-延迟发送

image.png

image.png

4.4、RocketMQ高级特性-处理失败

image.png

4.4、RocketMQ高级特性-消费重试和死信队列

image.png