kafka存储结构

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yaolong336/article/details/80047701

相关概念

  • topic 主题,特指kafka处理的消息源的不同分类
  • partition topic物理上的分组,一个topic可以分为多个partition
  • message 消息,是通信的基本单位

存储结构

topic结构

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

partition结构

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

segment结构

  • 由一对文件组成,一个索引文件,一个数据文件
  • 文件命名规则
    • 上一个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

示例

  • partition的结构
    partition文件夹内的截图
    可以发现,每对index和log就是一个segment

  • segment索引文件结构

00000000000000345678.index

1,0
3,248
7,1347
...
N,  278597

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 对应的segment日志数据文件结构

  • 00000000000000345678.log
    Message345679,起始位置:  0
    Message345680,起始位置: Message345679的MessageSize字段   (该消息没有索引)
    Message345681,起始位置: Message345679的MessageSize字段 + Message345680的MessageSize字段 =  248
    Message345682,起始位置: 248 + Message345681的MessageSize字段 (也没索引,可以看到直到第7条消息才重新有了索引)
    ...
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查找流程

    • 可以利用offset在partition中查找
    • 不能在整个topic中查找的,因为offset只保证在partition中唯一,有序
    • 流程如下(以查找offset为345683的message为例):
      • 二分查找确认segment为00000000000000345678.index和00000000000000345678.log
      • 在segment的index文件中, 345683-345678=5 ,接着再次二分查找所有元数据中offset小于等于该offset的值中最大的那个。即,小于等于5的所有数中最大的那一个,找到了(3,248)
      • 打开00000000000000345678.log,直接移动文件指针到248,即读到了offset为345681的消息
      • 顺序开始读取消息,直到读到offset为345683的message

    存储结构设计原因

    • 为什么有segment,而不是把partition直接设计成单个文件?
      • 方便消费后删除,可以节约空间,如果是单个文件,该文件由于会被不断写入,无法删除,则会无限增加。当需要清理时,则需要在保证写入的同时,清理该文件的前面已经过期的消息,效率十分低下。
    • 为什么有partition?
      • 方便水平扩展broker,如果不设计多个partition,那么当部署完成之时,topic就会被限定在一台机器上了,随着业务增加,最终会陷入瓶颈
    • 索引文件的作用
      • 使查找效率为O(1),即与文件大小无关,与查找的位置无关
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值