Kafka存储架构

104 阅读3分钟

核心概念

  • topic
  • partition
  • segment

topic

在逻辑上kafka以topic来组织和管理数据,生产者向topic发送数据,消费者从topic获取数据

partition

在物理存储上kafka以分区来存储数据,一个topic对应多个分区。分区在系统上是以文件夹的方式存在的,发送到这个分区的数据都存储在此文件夹下

partition命名规则

分区的命名是以topic为前缀,然后加上分区的序号,序号从0开始。一个topic名为kafka-test的主题,其分区命名为:kafka-test-0、kafka-test-1

segment

因为文件大小有限制并且生产者可以无限制的向分区中发送数据,导致分区不能只维护一个文件,所以每一个分区中的数据都会被分到多个segment分段中 每一个segment分段由三个文件组成:

  • log文件
  • index文件
  • timeindex文件

特点:

  1. 上述三个文件命名规则一致,只有后缀名的区别。其以log文件中第一条message的offset(全局offset)命名,但是需要注意,在kafka中,全局offset是64位10进制,这里只使用了20位10进制
  2. log文件大小限制由配置log.segment.bytes=1073741824决定,默认大小是1G,其内容会滚动新增。如果log文件写满之后会log rolling形成一个新文件存储消息
  3. index和timeindex文件开始时会分配10M的空间,log rolling后会将index和timeindex文件修剪为实际的大小

segment分段文件命名规则

文件命名以log文件第一条message的offset命名,其offset是分区全局的。第一个log文件的命名是从0开始的。 offset数值大小为64位,20位数字字符长度,没有数字使用0填充 比如:00000000000000000000.log、00000000000000000000.index、00000000000000000000.timeindex

log文件

kafka会将生产者发送的消息存放到log文件中,消息的格式为:

Message => Crc MagicByte Attributes Key Value
  Crc => int32
  MagicByte => int8
  Attributes => int8
  Timestamp => int64
  Key => bytes
  Value => bytes

key: 当需要将消息写入某个topic下的指定partition时,需要给定key值

value:实际的内容

其余的是消息的元数据

index位置索引文件

index文件是消息的位置索引文件 log日志每写入4K(可由log.index.interval.bytes设置),会写入一条索引信息到index文件中,因此index文件是稀疏索引

index文件中的索引项大小是8个字节,由相对offset(4个字节)+ position(4个字节)组成。相对offset是相对问log文件名。相对偏移量占用4个字节,全局偏移量占用8个字节,因此使用相对偏移量可以减少文件占用空间。

为了提高消息查询效率,kafka生成了index索引文件,那如何根据索引文件查询消息:

  1. 根据全局offset查询对应的index索引文件
  2. 使用全局offset-index索引文件名可以得到该全局offset在索引文件中的相对偏移量
  3. 使用二分查找查询该相对偏移量在索引文件查询符合范围的索引(因为索引文件是稀疏索引,所以可能该offset不存在索引项)
  4. 根据索引项的position地址从log文件中查询数据,同时将查询出的消息的全局offset与条件offset进行比较,不相等则查找下一条

timeindex索引文件

kafka在0.10.0.0版本之后在消息中增加了时间戳信息,同时,为了满足用户根据时间查询消息的需求,kafka增加了时间戳索引文件

timeindex的索引项大小是12个字节,由时间戳(8个字节)+ 相对offset(4个字节)组成。

根据timeindex查询消息时需要使用到index索引文件,因为timeindex索引项组成的第二部分是相对offset