01-basic

1. 绪论

image-20240330102618274

1. 优点

  1. 系统间解耦
  2. 异步通信
  3. 削峰填谷

2. 问题

  1. 单点问题
  2. 性能问题

3. AKF

  1. x:高可用
  2. y:业务划分(topic)
  3. z:分片、分治
  • Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以收集并处理用户在网站中的所有动作流数据以及物联网设备的采样信息

2. 初识kafka

  • 一般用作系统间解耦、异步通信、削峰填谷等作用。又提供了Kafka_streaming插件包实现了实时在线流处理。相比较一些专业的流处理框架不同,Kafka_Streaming计算是运行在应用端,具有简单、入门要求低、部署方便等优点
    • 消息队列 Message_Queue
    • Kafka_Streaming 流处理
  1. 系统间解耦
  2. 异步通信
  3. 削峰填谷
image-20220914192919230

3. 架构&概念

MQ工作模式两大类:

  1. 至多一次:生产者将数据写入消息系统,由消费者负责去消费。一旦消息被确认消费 ,由消息服务器主动删除队列中的数据。只允许被一个消费者消费,且不允许被重复消费
  2. 没有限制:生产者发完数据以后,该消息可以被多个消费者同时消费,同一个消费者可以多次消费同一个记录。消息服务器可以长时间存储海量消息
image-20220914194502635

1. 概念

  1. Topic:逻辑概念。指定具体queue
  2. Broker:物理概念。Kafka具体实例
  3. Partition:物理概念
  4. Record == Message

2. 架构

  1. Kafka以Topic形式负责分类集群中的Record,每一个Record属于一个Topic。每个Topic底层都会对应一组分区日志,用于持久化Topic中的Record
    • Record = key + value + timestamp
image-20220914195301703
  1. Kafka中,Topic的日志分区一定会有1个Borker担当Leader,其他的Broker担当的follower,Leader负责Topic数据读写操作,follower负责同步分区数据
    • 如果分区Leader宕机,该分区其他follower会选取出新的Leader继续负责分区读写。其中Leader的监控和Topic的部分元数据存储在Zookeeper中
image-20220914195833902

4. 分区&日志

  1. Kafka中Record通过Topic为单位进行管理,每个Topic通常会有多个订阅者。Kafka负责管理每个Topic的一组日志分区数据
  2. Producer将Record发布到Topic的一个Partition
    • eg:round-robin方式指定Partition,可以平衡负载。也可以根据Record的Key指定Partition
  3. 日志分区是一个有序的不可变的的日志序列,分区中每个Record都被分配了唯一的序列编号称为是offset
  4. Kafka会持久化Topic中的Record,硬盘存储日志文件,持久化时间是通过配置文件指定,默认168h
    • log.retention.hours=168
  5. Record分区内有序,分区间无序
  6. 高并发强调快速响应,大数据强调存储海量数据
image-20220914214818684

1. 优点

  • 允许日志扩展到超出单个服务器所能容纳的大小。每个单独的分区都可以有托管它的单独服务器
    • 一个Topic可能有很多分区,因此它可以处理任意数量的数据
  • 负载均衡。每个服务器充当某些分区Leader,也可能为其他分区Follwer
  • 增加consumer的并发能力

5. Consumer

  1. Consumer维护本次消费对应分区的偏移量,Consumer会在消费完一个批次数据后,会将下一个要消费的offset提交到kafka,因此对于每个Consumer而言可以随意的控制修改消费者的偏移量。多个消费者之间彼此相互独立
image-20220914212507191

1. Group

  1. Consumer与Group一对多关系,实现可伸缩性和容错能力。Topic中Record对Group进行广播。Record会被Group中的一个Consumer按策略消费
  2. Kafka会将Topic按照分区均分给一个Group下Consumer,如果Group下有新Consumer介入,会去接管Group内其他Consumer负责的某些分区,如果一个Consumer实例宕机,则由改Group中其他Consumer接管
  3. Record分区内有序,分区间无序。如果Record全局有序,通过Topic只有一个分区,Group只有一个Consumer来实现
  4. 分区内有序或者key进行分区策略已经满足绝大多数应用场景

2. 高吐

  • 高吞吐率。Record保存或缓存在磁盘上。即使普通服务器,Kafka轻松支持每秒百万级的写入,超过了大部分消息中间件。使Kafka在日志处理等海量数据场景广泛应用。Kafka会把收到消息写入到硬盘中,防止丢失数据。为了写入速度Kafka采用顺序写MMFile(Memory Mapped Files)内存映射技术

1. 顺序写

  1. 硬盘是机械结构,每次读写都会寻址 => 写入,寻址是一个“机械动作”,最耗时。所以硬盘最讨厌随机I/O,最喜欢顺序I/O
  2. 为了提高读写硬盘速度,Kafka使用顺序I/O。省去大量的内存开销以及IO寻址时间
  3. 单纯使用顺序写,性能也不可能和内存相比,因此Kafka数据并不是实时写入硬盘

2. MMFile

  1. 内存映射文件(Memory Mapped Files)
  2. Kafka利用现代操作系统分页存储,来使用内存提高I/O效率。在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page实现文件到物理内存的直接映射。完成MMP映射后,用户对内存的所有操作会被操作系统自动的刷新到磁盘上,极大地降低了IO使用率
image-20220914215643573

6. 生产者

  • Kafka响应客户端读取,底层使用ZeroCopy技术,磁盘数据无需拷贝到用户空间,直接通过内核空间传递输出

1. 传统IO

  1. 用户进程调用read等系统调用向操作系统发出IO请求,请求读取数据到自己的内存缓冲区。自己进入阻塞状态
  2. 操作系统收到请求后,进一步将IO请求发送磁盘
  3. 磁盘驱动器收到内核IO请求,把数据从磁盘读取到驱动器的缓冲中。此时不占用CPU。当驱动器的缓冲区被读满后,向内核发起中断信号告知自己缓冲区已满
  4. 内核收到中断,CPU将磁盘驱动器的缓存的数据拷贝到内核缓冲区中
  5. 如果内核缓冲区的数据少于用户申请的读的数据,重复步骤3跟步骤4,直到内核缓冲区的数据足够多为止
  6. 将数据从内核缓冲区拷贝到用户缓冲区,同时从系统调用中返回。完成任务
image-20220914220555099

2. DMA

  • (Direct_Memory_Access,直接存储器访问)
  1. 用户进程调用read等系统调用向操作系统发出IO请求,请求读取数据到自己的内存缓冲区。自己进入阻塞状态
  2. 操作系统收到请求后,进一步将IO请求发送DMA。然后让出CPU
  3. DMA进一步将IO请求发送给磁盘。磁盘驱动器将数据从磁盘读取到驱动器的缓冲中。当驱动器的缓冲区被读满后,向DMA发起中断信号告知自己缓冲区已满
  4. DMA收到磁盘驱动器的信号,将磁盘驱动器的缓存中的数据拷贝到内核缓冲区中,此时不占用CPU。这个时候只要内核缓冲区的数据少于用户申请的读的数据,内核就会一直重复步骤3跟步骤4,直到内核缓冲区的数据足够多为止
  5. 当DMA读取了足够多的数据,就会发送中断信号给CPU
  6. CPU收到DMA的信号,将数据从内核拷贝到用户空间,系统调用返回
image-20220914224346023
  • 跟传统IO中断模式相比,DMA就是CPU的一个代理,它负责了一部分的拷贝工作,从而减轻了CPU负担

3. ZeroCopy

image-20220914224527750
  1. 磁盘数据被copy到内核缓冲区
  2. 从内核缓冲区copy到用户缓冲区
  3. 用户缓冲区copy到内核与socket相关的缓冲区
  4. 从socket缓冲区copy到相关协议引擎发送出去
image-20220914224734010
  1. 磁盘中数据被copy到内核缓冲区
  2. 内核缓冲区copy到内核与socket相关的缓冲区
  3. 从socket缓冲区copy到相关协议引擎发送出去

7. 总结

  1. 队列使用场景
    1. 系统间解耦
    2. 异步通信
    3. 削峰填谷
  2. Kafka架构和基本概念
    1. topic、partitions、offset、顺序写、MMF、ZeroCopy
    2. 生产者、消费者|消费者组