kafka-文件存储机制
topic是逻辑上的概念,而partition是物理上的概念,每一个partiton对应一个log文件,该log文件中存储的是producer生产的数据。producer生产的数据会不断被追加到该log文件末端,为了防止log文件过大导致数据定位效率低下,kafka采取了分片和索引
机制,将每个partition分为多个segment(分片),每个segment包括:index文件、log文件和timeindex等文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区号,例如:test-0
- log文件:日志文件,默认最大1g
- index文件:偏移量索引文件,为稀疏索引,大约每往log文件写入4kb数据,会往index文件写入一条纪录。index文件中保存的offset为相对offset,这样能够确保offset的值所占空间不会过大,因此能将offset的值控制在固定大小
- timeindex文件:时间戳索引文件
index和log文件以当前segment的第一条消息的offset命名
查找流程:
- 根据目标offset定位到segment文件
- 在index文件中找到小于等于目标offset的最大offset对应的索引项
- 通过索引项定位到log文件的指定位置
- 向下遍历找到目标数据
文件清理策略
kafka中默认的日志保存时间为7天,默认的检测周期是5分钟
超过时间后kafka提供delete和compact
两种日志清理策略,通过log.cleanup.policy设置
-
delete:日志删除,默认策略
- 基于时间:默认打开,以segment中所有纪录中的最大时间戳作为该文件时间戳。如果一个log文件没有满它的最大时间戳永远不会过期
- 基于大小:默认关闭,超过设置的所有日志总大小,删除最早的segment。通过log.retention.bytes设置,默认-1表示无限大
-
compact:日志压缩,对于相同key的不同value值,只保留最后一个
压缩后的offset可能不是连续的,当从这些offset消费消息时,将会拿到比这个offset大的offset对应的消息,并从这个位置开始消费
顺序写磁盘
kafka的producer生产的数据,要写入到log文件中,写的过程是一直追加到文件末端,为顺序写。顺序写之所以快,是因为省去了大量磁头寻址的时间
零拷贝
kafka的数据加工处理操作交由生产者和消费者处理。kafkabroker应用层不关心存储的数据,所以就不用走应用层,传输效率高
页缓存
pagecache页缓存:kafka重度依赖底层操作系统提供的pagecache功能。当上一层有写操作时,操作系统只是将数据写入pagecache。当读操作发生时,先从pagecache中查找,如果找不到,再去磁盘中读取。实际上pagecache是把尽可能多的空闲内存当作磁盘缓存来使用