核心概念
- 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文件
特点:
- 上述三个文件命名规则一致,只有后缀名的区别。其以log文件中第一条message的offset(全局offset)命名,但是需要注意,在kafka中,全局offset是64位10进制,这里只使用了20位10进制
- log文件大小限制由配置log.segment.bytes=1073741824决定,默认大小是1G,其内容会滚动新增。如果log文件写满之后会log rolling形成一个新文件存储消息
- 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索引文件,那如何根据索引文件查询消息:
- 根据全局offset查询对应的index索引文件
- 使用全局offset-index索引文件名可以得到该全局offset在索引文件中的相对偏移量
- 使用二分查找查询该相对偏移量在索引文件查询符合范围的索引(因为索引文件是稀疏索引,所以可能该offset不存在索引项)
- 根据索引项的position地址从log文件中查询数据,同时将查询出的消息的全局offset与条件offset进行比较,不相等则查找下一条
timeindex索引文件
kafka在0.10.0.0版本之后在消息中增加了时间戳信息,同时,为了满足用户根据时间查询消息的需求,kafka增加了时间戳索引文件
timeindex的索引项大小是12个字节,由时间戳(8个字节)+ 相对offset(4个字节)组成。
根据timeindex查询消息时需要使用到index索引文件,因为timeindex索引项组成的第二部分是相对offset