0
点赞
收藏
分享

微信扫一扫

Kafka工作流程及文件存储机制

Kafka工作流程概述

Kafka工作流程及文件存储机制_数据文件

Kafka中消息是以topic进行分类的,生产者生产消息,消费者消费消息,都是面向topic的。
topic是逻辑上的概念,一般一个业务就是一个topic,而partition是物理上的概念,每个partition对应于一个log文件,该log文件中存储的就是producer生产的数据。Producer生产的数据会被不断追加到该log文件末端,且每条数据都有自己的offset。消费者组中的每个消费者,都会实时记录自己消费到了哪个offset,以便出错恢复时,从上次的位置继续消费。
每个partition都有自己的Leader和Follower.

文件存储机制

Kafka工作流程及文件存储机制_kafka_02

概述:
一个partiton对应一个目录,一个目录一个log, log太大了,查找起来不方便,我们会给log文件切分成多个segment,每个segment对应一个.log文件,一个.index文件.

详细解答:
由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment。
每个partition(目录)相当于一个巨型文件被平均分配到多个大小相等的segment(段)数据文件中(每个segment 文件中消息数量不一定相等),这种特性也方便old segment的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个partition只需要支持顺序读写就行,segment的文件生命周期由服务端配置参数(log.segment.bytes,log.roll.{ms,hours}等若干参数)决定。
每个segment对应两个文件——“.index”文件和“.log”文件。分别表示为segment索引文件和数据文件(引入索引文件的目的就是便于利用二分查找快速定位message位置)。这两个文件的命令规则为:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充。
这些文件位于一个文件夹下(partition目录),该文件夹的命名规则为:topic名称+分区序号。例如,first这个topic有三个分区,则其对应的文件夹为first-0,first-1,first-2。

00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log

index和log文件以当前segment的第一条消息的offset命名。下图为index文件和log文件的结构示意图。
![image.png](https://img-blog.csdnimg.cn/img_convert/86e15d82195220a4f0ce4b78ea7421b7.png#align=left&display=inline&height=365&margin=[object Object]&name=image.png&originHeight=365&originWidth=693&size=25676&status=done&style=none&width=693)
“.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中message的物理偏移地址。

工作流程详细分析

发送数据

follower的同步流程:

Kafka工作流程及文件存储机制_数据_03

  1. Producer在写入数据的时候永远的找leader,不会直接将数据写入follower
  2. 消息写入leader后,follower是主动的去leader进行同步的!
  3. producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的
    不存在的topic写数据,kafka会自动创建topic,分区和副本的数量根据默认配置都是1。

分区:

ACK应答机制:

保存数据

Kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高),将数据保存在磁盘。

任何发布到 Partition 的消息都会被追加到 Partition 数据文件的尾部,且消息消费后不会删除(删除策略是针对过期的 Segment 文件),这样的顺序写磁盘操作让 Kafka 的效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是 Kafka 高吞吐率的一个很重要的保证)。

Partition 结构:

Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。
Kafka工作流程及文件存储机制_数据文件_04

如上图,这个partition有三组segment文件,每个log文件的大小是一样的,但是存储的message数量是不一定相等的(每条的message大小不一致)。文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题

Message结构:

上面说到log文件就实际是存储message的地方,我们在producer往kafka写入的也是一条一条的message,message主要包含消息体、消息大小、offset、压缩类型……等等
offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
消息大小:消息大小占用4byte,用于描述消息的大小。
消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。

存储策略:

无论消息是否被消费,kafka都会保存所有的消息(存在磁盘)。那对于旧数据有什么删除策略呢?
    基于时间,默认配置是168小时(7天)。
    基于大小,默认配置是1073741824。
  需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能

消费数据

Kafka采用的是点对点的模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader去拉取

  1. 多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id。
    2.同一个消费组的消费者可以消费同一topic不同分区的数据,但是不会组内多个消费者消费同一分区的数据!!!
    3. 消费者数少于分区:会出现某个消费者消费多个partition数据的情况(此时消费的速度不及只处理一个partition的消费者的处理速度)
    4.消费者数多于分区:多出来的消费者不消费任何partition的数据。
    建议消费者组的consumer的数量与partition的数量一致!

搜索数据

假如现在需要查找一个offset为368801的message是什么样的过程呢?用一个例子来解释一下搜索过程
Kafka工作流程及文件存储机制_数据文件_05

  1. 先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。
    2.打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。
  2. 根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。

注意该index 文件并不是从0开始,也不是每次递增1的,这是因为 Kafka 采取稀疏索引存储的方式,每隔一定字节的数据建立一条索引,它减少了索引文件大小,使得能够把 index 映射到内存,降低了查询时的磁盘 IO 开销,同时也并没有给查询带来太多的时间消耗。
小结:这套机制是建立在offset为有序的基础上,利用segment+有序offset+稀疏索引+二分查找+顺序查找****等多种手段来高效的查找数据!至此,消费者就能拿到需要处理的数据进行处理了。

消费者记录位置的方式


早期的版本:消费者将消费到的offset维护zookeeper中,consumer每间隔一段时间上报一次,这里容易导致重复消费,且高并发时和ZK频繁交互,性能不好!
新的版本:消费者消费到的offset已经直接维护在kafk集群的__consumer_offsets这个topic中!

参考:

尚硅谷Kafka和​


举报

相关推荐

0 条评论