消息队列(上)

114 阅读5分钟

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

消息队列(上)

前生今世

消息队列发展历程

image.png

业界消息队列对比

  • Kafka :分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
  • RocketMQ :低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
  • Pulsar :是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计
  • BMQ :和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群

消息队列-Kafka

使用场景

image.png

如何使用Kafka

graph TD
创建集群 --> 新增Topic --> 编写生产者逻辑 --> 编写消费者逻辑
  • 第一步: 首先需要创建一个Kafka集群
  • 第二步: 需要在这个集群中创建—个Topic,并且设置好分片数量
  • 第三步: 引入对应语言的SDK,配置好集群和Topic等参数,初始化一个生产者,调用Send方法,将你的Hello World发送出去
  • 第四步: 引入对应语言的SDK,配置好集群和Topic等参数,初始化一个消费者,调用Poll方法,你将收到你刚刚发送的Hello World

基本概念

image.png

  • Topic:逻辑队列,不同Topic可以建立不同的
  • TopicCluster:物理集群,每个集群中可以建立多个不同的
  • TopicProducer:生产者,负责将业务消息发送到Topic中
  • Consumer:消费者,负责消费Topic中的消息
  • ConsumerGroup:消费者组,不同组Consumer消费进度互不干涉

基本概念-Offset

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

image.png

基本概念-Replica

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

image.png

数据复制

image.png

Kafka架构

ZooKeeper:负责存储集群元信息,包括分区分配信息等

image.png

一条消息的自述

image.png 从一条消息的视角,看看为什么Kafka 能支撑这么高的吞吐?

image.png 如果发送一条消息,等到其成功后再发一条会有什么问题?

Producer-批量发送

image.png

Producer-数据压缩

image.png

Broker-数据的存储

image.png

Broker消息文件结构

image.png 数据路径:/Topic/Partition/Segment/(log | index | timeindex | ...)

Broker-磁盘结构

移动磁头找到对应磁道,磁盘转动,找到对应扇区,最后写入。寻道成本比较高,因此顺序写可以减少寻道所带来的时间成本。

image.png

Broker-顺序写

采用顺序写的方式进行写入,以提高写入效率

image.png

Broker-如何找到消息

Consumer通过发送FetchRequest 请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消 息大小窗口发送给Consumer,寻找数据这个细节是如何做到的呢?

image.png

Broker 偏移量索引文件

目标:寻找offset = 28

image.png 二分找到小于目标offset的最大文件

二分找到小于目标offset的最大索引位置

image.png

Broker 时间戳索引文件

二分找到小于目标时间戳最大的索引位置,在通过寻找offset的方式找到最终数据。

image.png

Broker-传统数据拷贝

image.png

Broker-零拷贝

image.png

Consumer-消息的接收端

image.png

Consumer-Low Level

通过手动进行分配,哪一个Consumer消费哪一个 Partition完全由业务来决定。

image.png

Consumer-High Level

image.png

Consumer Rebalance

image.png

刚刚总共讲了哪一些可以帮助Kafka提高吞吐或者稳定性的功能?

Producer:批量发送、数据压缩

Broker:顺序写,消息索引,零拷贝

Consumer : Rebalance

Kafka-数据复制问题

通过前面的介绍我们可以和道,对于Kdka来说,每一个Broker上都有不同itopi分区的不同副本,而每一个副本,会将其数据存信到该‰aRc节点上面,对于不同的节点之间,通过副本直接的数据复 来保证数据的最终—致性,与集群的高可用。

image.png

Kafka-重启操作

image.png

Kafka-替换、扩容、缩容

如果是替换,或者扩容,或者缩容操作呢,我们来看看。 如果是替换,和刚刚的重启有什么区别,其实替换,本质上来讲就是一个需要追更多数据的重启操作,因为正常重启只需要追一小部分,而替换,则是需要复制整个ese的数强,时间会更长扩容呢,当分片分配到新的机器上以后,也是相当于要从0开始复制—些新的副本 而缩容,缩容节点上面的分片也会分片到集群中剩余节点上面,分配过去的副本也会从0开始去复制数据 以上三个操作均有数据复制所带来的时间成本问题,所以对于Kafka来说,运维操作所带来的时间成本是不容忽视的

image.png

Kafka-负载不均衡

这个场景当中,同一个Topic有4个分片,两副本,可以看到,对于分片1来说,数据量是明显比其他分片要大的,当我们机器IO达到瓶颈的时候,可能就需要把第一台Broker上面的partition3迁移到其他负载小的Broker上面,接着往下看

image.png

image.png

Kafka-问题总结

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