消息队列|青训营笔记

74 阅读5分钟

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

消息队列的作用

  • 解耦
  • 削峰
  • 异步
  • 日志处理

Kafka详解

  • kafka基础

    kafka是消息引擎,分布式流处理平台

    • 术语

      • producer: 生产者,即消息的产生者,消息的入口

      • kafka cluster:kafka集群,一台或者多台服务器组成;

      • Broker: kafka节点,这里假设一个kafka节点仅对应一个Broker;每个Broker都有一个不重复的编号,如broker-0,broker-1

      • Topic: 消息的主题(消息的分类),一个broker可以创建多个topic,kafka的数据保存在topic中,通常一个业务线对应一个topic,每类应用或者数据可以创建一个Topic

      • Partition: 分区,用于做负载均衡,每个Topic可以包含多个分区,每个分区上存储者不同的数据,partition的表现形式就是一个一个的文件

      • replication:备份机制,每个分区对应的副本replica,当主分区故障时会选择一个follower成为新的leader;follwer和leader必须属于不同的机器,同一机器对于partition也只会存在一份replication;作用是请求Leader同步最新的数据

        • replica在leader中会进行记录,分为两个集合,一个是ISR集合,一个OSR集合;如果该副本与leader的偏移在一定阈值之内就在ISR集合中,如果落后leader过多就会被放入到OSR集合中;只有ISR副本中的节点才有机会成为该partition的leader
        • 分区 ISR 集合中的每个副本都会维护自己的 LEO,而 ISR 集合中最小的LEO 即为分区的 HW
      • cosumer:消费者,生产者以及消费者只与 Leader 交互

      • 消费者组:由多个消费者组成

      • rebalance: 消费者组内消费者数量变化,订阅的topic变化、topic的partition变化,消费者实例自动重新分配订阅主题分区的过程

      • offset:第一种分区offset,表示消息在分区中的位置索引;第二种消费offset,表示消费者读取到的位置

    • 工作流程

      • 每个broker启动后需要先在zk上进行注册,id可以配置也可以自动生成
      • 生产者启动时会有引导节点,与指定的broker建立连接(通常我们不用配置所有的 broker 服务器地址,否则 kafka 会和配置的所有 broker 都建立 TCP 连接)
      • 连接建立完成发送请求获取所有broker信息(如主题,分区,副本等),与所有broker建立TCP连接
      • 发送消息
      • 消费者与生产者相同选择一个broker建立连接,发送请求找到协调者所在的broker
      • 与协调者broker建立连接获取元数据
      • 根据分区leader所在的broker分别创建连接
      • 开始消费消息
    • 控制器

      • 控制器来维护 kafka 集群的正常运行,例如 ISR 列表的变更,broker 的上线或者下线,topic 的创建,分区的指定等;
      • kafka2中controller 的选举需要通过 zk 来实现;kafka3可以通过采用kraft指定控制器需要设置Process.Roles参数
      • Kafka 控制器会将其元数据存储在 Kafka 分区中,而不是存储在 ZooKeeper 中。但是,由于控制器依赖于该分区,因此分区本身不能依赖控制器来进行领导者选举之类的事情。而是,管理该分区的节点必须实现自我管理的 Raft 仲裁。
      • 在 kafka3.0 之前的的版本当中,主要是借助于 controller 来进行 leader partition 的选举,而在 3.0 协议当中,使用了 KRaft 来实现自己选择 leader,并最终令所有节点达成共识,这样简化了 controller 的选举过程
    • 选择partition的原则

      在kafka中如果某个Topic有多个分区,生产者如果选择分区

      • 在写入时可以指定分区,如果有指定则写入对应的分区
      • 没有指定分区,设置了key,可以通过key的hash计算出对应的分区
      • 既没有指定也没有设置key,会采用轮询的方式每一段时间取一部分数据放到某分区中
      • 自定义
      • 每个分区内部消息有序,不同分区包含不同的消息;在每个分区中消息都有一个顺序的唯一ID,这个标识称为offset,既偏移量
      • 每个partition下都会有多组的segment文件,每组segment文件又包含.index, .log, .timeindex文件,.index用于检索消息,.log存放数据
    • ACK应答机制

      生产者在向kafka发送数据时,可以设置不同的级别对应kafka是否收到;如果往不存在的topic写消息,kafka会自动创建对应的topic,partition和replication,数量都是1

      • 0:表示生产者不需要等待kafka集群回复ACK,不确保消息发送成功,效率最高安全性低
      • 1:代表生产者往集群中发送数据时只要Leader应答就可以发送下一条,只确保Leader成功
      • all;需要确保Leader和所有对应的follower都成功接受,安全性最高效率最低
    • 持久化数据

      • Kafka 使用消息日志(Log)来保存数据,随机写改为顺序写;一个日志又近一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,Kafka 会自动切分出一个新的日志段,并将老的日志段封存起来。Kafka 在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的
    • 消费数据

      • 多个消费者可以组成一个消费组,并用一个标签标识这个消费组。一个消费组中不同的消息实例可以运行在不同的服务器或者进程上
      • 如果所有消费者属于一个消费组,那么队列中的消息会均衡的分配给消息组中的某个消费者,相当于消费者处理消息时的负载均衡
      • 如果所有的消费者属于不同的消费组,那么每一条记录会被广播给所有的消费者,相当于消息会广播给每个消费组,每个消费组中由一个消费者进行接收处理