我们知道,生产者发送给kafka的数据肯定是需要存储的,存储意味着数据落盘,但是这个数据存储的结构是怎样的呢?
不妨先来了解下kafka文件存储机制
Topic是逻辑上的概念,而partition是物理上的概念,每个partition对应于一个log文件,该log文件中存储的就是Producer生产的数据;Producer生产的数据会被不断追加到该log文件末端,为防止log文件过大导致数据定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment;每个segment包括:“.index”文件、“.log”文件和.timeindex等文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号,例如:first-0;
总体的文件结构如下图所示:
对上面的文件结构再做几点补充说明:
一个partition分为多个segment.log 日志文件 .index 偏移量索引文件 .timeindex 时间戳索引文件其他文件index和log文件以当前segment的第一条消息的offset命名
下面我们进入到某个topic目录下实际观察下吧
我们以zcy333这个为例进行说明,首先先这个topic下面随机发送几条数据,直接使用kafka命令窗口发送消息即可
进入到保持数据的目录下,可以看到对于这个topic来说,由于是3个分区,所以每个分区都存有以 topic开头的几个目录,我们不妨进入到某个目录下
进入到zcy333-0目录下,可以看到该目录下正好是上文所说,分别包括 .index .log 以及 .timeindex的几个文件
既然数据是存放在log文件中,查看下吧,通过cat命令,发现这是一堆乱码,很明显这是经过序列化后的数据
使用kafka提供的反序列化工具,进入到bin目录下,执行下面的命令可以查看log日志的数据
./kafka-run-class.sh kafka.tools.DumpLogSegments --files /usr/local/soft/kafka/datas/data1/zcy123-0/00000000000000000000.log
执行后,log里面清楚的记录了一条数据的完整的存储信息
使用下面的命令查看index数据
./kafka-run-class.sh kafka.tools.DumpLogSegments --files /usr/local/soft/kafka/datas/data1/zcy123-0/00000000000000000000.index
index 文件和 log 文件详解
通常情况下,按照我们对索引的理解,比如mysql的innodb引擎为例,数据和索引的存储其关系是一一对应的,即可以通过索引定位到一条数据,但是kafka的做法采用的是 “稀疏索引”,即并非进入log文件的每条数据都在索引文件中进行记录
而是当log中的文件数累计到一定的数量才会在index文件中记录一次,就像下面的这个表格,当查找数据时,根据一个范围去定位数据落在那个文件中,然后进行读取返回



