Kafka数据内存存储结构(四)

本文详细介绍了Kafka的存储结构,包括topic、partition、segment及其索引文件的组织形式。Kafka通过分布式和分区实现高性能,每个partition由一系列按offset排序的message组成。message查找通过offset在segment文件的稀疏索引中进行二分查找,实现高效定位。文章还探讨了Kafka如何利用这种结构实现高并发存储和消费。

4. Kafka 存储形式

4.1 存储结构

image-20201104154440754

通过上图,我们可以大概了解到一点,Kafka是通过主题进行对数据进行分类的,而一个主题可以划分为多个partition分区,同一topic的不同partition可能分布在不同机器上,进而实现分布式高性能的特点。对于partition在系统中是一个文件夹,其中可能包含多个segment。

我们可以设置segment在内存中的大小,当保存的消息大于segment的大小时,会再建一个segment。一个segment段由三个文件组成,分别为 .log , .index , .timeindex .

topic结构

  • topic包含多个partition,
  • topic只是逻辑概念,不涉及到存储,partition才是物理概念
  • 同一topic的不同partition可能分布在不同机器上

partition结构

  • partition是一个文件夹,其中包含多个segment
  • 如果其中有n个segment,则共有2*n个文件
  • 每个partition是一个有序的队列
  • partition中的每条消息都会分配一个有序的id,即offset

segment结构

  • 由一对文件组成,一个稀疏索引文件(.index),一个数据文件(.log),一个时间索引文件(.timeindex)
  • 文件命名规则
    • 上一个segment在partition中的最大offset数值,即,比如00000000000000345678.log文件中的第一条消息的offset为345679
    • 最大为64位的long,不足位数补0,如00000000000000345678.log
    • 索引文件后缀.index,日志数据文件后缀.log

segment索引文件结构

  • 存储一系列的元数据,每条元数据就是一条索引
  • 元数据条数小于消息条数,是稀疏索引
  • 元数据(即索引)构成
    • 索引所指向的message在数据日志文件中的相对序号,即相对的offset,从1开始,该相对offset加上文件名当中的值就是该message在整个partition中的绝对offset了
    • 索引所指向的message在数据日志文件中的位置,即文件游标,从0开始,方便直接指定游标打开数据文件

segment日志数据文件结构

  • 存储一系列的message

message结构

  • offset 偏移量,消息的唯一标识,通过offset能找到唯一消息,类型long 8bytes
  • MessageSize 消息长度,类型int32 4bytes
  • crc32校验码, 4bytes,校验message
  • magic, 表示本次发布kafka服务程序协议版本号 1byte
  • attributes 独立版本,标识压缩类型,编码类型 1byte
  • key length 4bytes 当key length=-1时,key字段可不写
  • key 可选
  • payload 实际消息内容

message特点

  • message是无状态的,即不会标识是否已被消费过
  • message不能同时被多个consumer来消费,可以等前一个消费完成,下一个继续消费。
  • consumer可以同时消费多条message

4.2 kafka如何实现高并发存储-如何找到一条需要消费的数据(阿里)

kafka的底层用了稀疏索引的方式,使用了二分查找法,其实很多索引都是二分查找法。 二分查找法的时间复杂度:O(logn)。除了Kafka外,其实 redis,B+树的底层都采用了二分查找法

参考: redis的索引底层的 跳表原理 实现 聊聊Mysql索引和redis跳表 —redis的跳表原理 (阿里)

参考: :一步步分析为什么B+树适合作为索引的结构 以及索引原理 (阿里面试)

参考::各种排序算法的时间复杂度和空间复杂度(阿里)

在partition中如何通过offset查找message?

我们都知道,Kafka消费者读取数据时,只需要通过一个offset就可以精准的拉取数据,例如读取offset=368776的message,需要通过下面2个步骤查找。

第一步查找segment file

image-20201106142619322

上述图2为例,

其中第一个文件00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0. 第二个文件00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1. 同样,第三个文件00000000000000737337.index的起始偏移量为737338=737337 + 1,其他后续文件依次类推,以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。

当offset=368776时定位到00000000000000368769.index|log

第二步通过segment file查找message

通过第一步定位到segment file,当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和 00000000000000368769.log的物理偏移地址,然后再通过00000000000000368769.log顺序查找直到 offset=368776为止。

从上述图3可知这样做的优点,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值