Kafka之存储机制
-
producer以及consumer如何知道该去哪个broker传送以及消费数据
producer可以指定一个或者多个broker的信息(ip:port),来获取kafka集群的元信息(最好多指定几个,否则这个broker连接不上了,就over了)。每个broker,topic有多少partition,每个partition在哪个broker上,该信息会存储到broker的内存之中进行维护。而consumer是通过连接ZK,发现kafka集群的元信息,从而找到了对应的数据位置
-
存储文件路径
存储文件路径见配置.
root@root:/usr/local/kafka/kafka_2.12-2.0.0/config# cat server.properties | grep log.dir log.dirs=/usr/local/kafka/kafka_2.12-2.0.0/logs
在kafka集群中,每个broker中有多个topic。在每个topic中又有多个partition,每个partition为一个分区。kafka的分区命名规则为topic的名称+有序序号,这个序号从0开始依次增加,如test-0
root@root:/usr/local/kafka/kafka_2.12-2.0.0/logs$ cd test-0 root@root:/usr/local/kafka/kafka_2.12-2.0.0/logs/test-0$ ll total 48 drwxr-xr-x 2 root root 4096 Mar 18 21:54 ./ drwxr-xr-x 60 root root 36864 Mar 23 20:24 ../ -rw-r--r-- 1 root root 10485760 Mar 18 21:08 00000000000000000000.index -rw-r--r-- 1 root root 222 Mar 18 21:58 00000000000000000000.log -rw-r--r-- 1 root root 10485756 Mar 18 21:08 00000000000000000000.timeindex -rw-r--r-- 1 root root 8 Mar 18 21:54 leader-epoch-checkpoint
每一个partion(文件夹)会存储多个大小相等segment(段)数据文件,segment文件生命周期由服务端配置參数log.segment.bytes决定
segment文件由2大部分组成,分别为index file和data file,后缀”.index”和“.log”分别表示为segment索引文件、数据文件
segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充
由于是对segment文件追加写,故实现了对磁盘文件的顺序写,避免磁盘随机写时的磁盘寻道的开销,同时由于是追加写,故写入速度与磁盘文件大小无
-
segment数据文件存储结构
data file由许多message组成。物理结构如下图所示:
关键字 | 解释说明 |
8 byte offset | offset在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message |
4 byte message size | message大小 |
4 byte CRC32 | 用crc32校验message |
1 byte “magic" | 表示本次发布Kafka服务程序协议版本号 |
1 byte “attributes" | 表示为独立版本、或标识压缩类型、或编码类型。 |
4 byte key length | 表示key的长度,当key为-1时,K byte key字段不填 |
K byte key | 可选 |
value bytes payload | 表示实际消息数据。 |
-
segment索引文件存储结构
OffsetIndex索引文件的格式: 每一个索引项为8字节,其中相对offset占用4字节,消息的物理地址(position)占用4个字节.这样就实现了相对offset与物理地址的映射。
相对offset表示消息相对于baseOffSet的偏移量,例如分段后的一个日志文件的baseOffset是32450,它的文件名就是32450.log,那么offset为32455的消息在相对offset就是32455-32450 = 5。
position,表示该条Message在数据文件中的绝对位置。只要打开文件并移动文件指针到这个position就可以读取对应的Message了。index文件中并没有为数据文件中的每条Message建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。
index<—->data file对应关系物理结构如下:
-
过期数据清理
达到下面配置限制时,会删除segment文件,而不是删除其中部分记录
# The minimum age of a log file to be eligible for deletion due to age 消息存储时间 log.retention.hours=168 # A size-based retention policy for logs.消息存储的字节数.和hours任何一个达到限制都会删除数据 #log.retention.bytes=1073741824