每个topic,分为多个partition,每个partition在文件系统当中是一个文件夹。java
而每个partition当中,又分红了多个segment,每一个segment,包括了2个文件,.index文件和.log文件,分别是消息的索引信息和消息内容。而文件的名字形以下面的格式异步
00000000000000000000.logsocket
00000000000000000000.index线程
0000000000000999.log设计
0000000000000999.index索引
文件名的就是消息在本分区当中的序号,以上面的文件为例,第一个segment当中存储了0-999的消息,而第二个segment从1000开始。内存
须要注意的是segment的划分规则,目前据个人研究,是综合了2方面的因素,一个是设定的segment的大小,满了天然会再来一个segment;第二个因素是时间的因素,好比某个topic长时间没有消息写入,那么在有新消息进来的时候,极可能会从新建一个segment,这样作的目的是为了方便在消息失效的时候,针对整个segment进行删除。it
index文件当中,包含了2部份内容,分别是消息的在本segment当中的编号和物理offset。这里须要注意的是,在index文件当中,并非存储了每一条消息的的索引信息,而是采用了 稀疏索引的策略,也就是隔几个存一个索引。io
在查找一条消息的时候,首先是根据segment的名字和输入的消息编号,查找所在的segment,以后在根据index文件找到消息的具体位置。file
写过程:
消息从java堆转入page cache(即物理内存)
由异步线程刷盘,消息从page cache刷入磁盘
读过程:
消息直接从page cache转入socket发送出去
当从page cache没有找到相应数据时,此时会产生磁盘IO,从磁 盘Load消息到page cache,而后直接从socket发出去
存储设计的优势:
Kafka把topic中一个parition大文件分红多个小文件段,经过多个小文件段,就容易按期清除或删除已经消费完文件,减小磁盘占用。
经过索引信息能够快速定位message
经过index元数据所有映射到memory,能够避免segment file的IO磁盘操做
经过索引文件稀疏存储,能够大幅下降index文件元数据占用空间大小