消息队列 | 青训营笔记

62 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

四个问题:

  1. 系统崩溃

    解决:解耦

    image-20230213193838210

  2. 服务处理能力有限

    解决:削峰

    image-20230213193924075

  3. 链路耗时长尾

    解决:异步

    image-20230213193935176

  4. 日志如何处理

    image-20230213194046940

消息队列:保存消息的一个容器,本质上是一个队列,需要支持高吞吐、高并发、高可用

Kafka

使用Kafka流程:

创建集群->新增Topic->编写生产者逻辑->编写消费者逻辑

基本概念:

Topic:逻辑队列,不同的业务场景就是不同的Topic

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

Produce、Consumer:将消息发送到队列中,从队列中取消息

ConsumerGroup:消费者组

image-20230213195247418

offset:消息在partition内的相对位置,可以理解为唯一的ID,在partition内部严格递增

image-20230213195339777

Replica:每个分片有多个副本,Leader Replica将会从ISR中选出。

Follower会不断从Leader上拉取数据下来

image-20230213195431650

数据复制

image-20230213195843905

架构

ZooKeeper:与Controller一起存储元数据信息等

image-20230213200015424

写入流程:

Producer将多个消息写入Batch中,批量发送增加吞吐量,然后进行压缩,发给Broker(在消息队列中),然后等待Broker返回是否写入成功

image-20230213201847143

Broker消息文件结构:

image-20230213202036885

Broker写入消息时采用顺序写的方式,提高写入效率

Consumer通过发送FetchRequest请求数据消息,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer

具体找offset偏移量的文件:

image-20230213202459568

通过二分查找找到对应的三个文件

数据复制:Broker零拷贝:直接将数据发送到NIC Buffer,减少内存拷贝次数

image-20230213202942511

ConsumerGruop的分配方式:每一Group将所有Partition全拷贝

  • 手动分配

    image-20230213203143858

  • 自动分配

    在Broker对于不同的Consumer建立不同的Coordinator,帮助实现自动分配

    image-20230213203342639

缺点:

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

BMQ

兼容Kafka协议,存算分离(Broker上存储的数据用另外一个存储机构存储),云原生消息队列

架构图

image-20230213205239710

对于运维来说,重启、替换、扩容、缩容都可以在秒级完成

写文件流程

image-20230213210108915

文件结构对比:

image-20230213205701009

后面看不懂了