本文次要有两大块内容:

  • patition里的segment file
  • 如何查找一条音讯

先看下几个根本的概念:

  • partition:topic物理上的分组,一个topic下能够有多个partition,每个partion是有序的
  • segment:每个patition由多个segment file组成
  • offset:partition中的每个音讯都有一个间断的序列号叫做offset,用于标识惟一一条partition里的音讯
  • message:kafka中最小的存储单位,a commit log.

kafka的message是以topic为根本单位,不同的topic之间的互相独立的,每个topic又能够分为几个不同的partition,每个partition存储一部分message。

patition里的segment file

partition里的segment file是以文件夹的模式存储在Broker上的,它们大小相等(具体大小能够通过config/server.properties中进行设置)。

segment file的特点

  1. 组成。由两局部组成,别离是index file与data file,这两个文件一一对应,后缀别离为.index与.log
  2. 命名。partition的第一个segment从0开始,后续每个segment文件名为上一个segment文件最初一条音讯的offset,20位数字字符长度,有余用0填充。

index file与data file的关系
先看一张图

索引文件中存储着元数据,数据文件存储着音讯,依据索引文件中的元数据咱们能够疾速定位到数据文件里相应的音讯。以索引文件中的3,497为例,3指的是在数据文件中的第3个segment,它是一个逻辑地址;而497指的是该音讯在segment里的物理偏移地址为497。
从上图咱们还能够晓得在00000000000000368769.log文件里的Message368772这个segment在全局partition示意第368772个message,也就是通过文件名咱们就能够晓得它所在的全局offset。

data file物理构造

在图里咱们能够分明地晓得data file里记录着音讯的大小(size)与具体内容(payload)等信息

如何查找一条音讯

partition的音讯文件为什么要别离生成index file与data file这两个文件呢?很大一部分起因就是为了不便音讯的查找。这里也能看出kafka能够高效查找音讯的两个伎俩:分段与索引。

数据文件的分段

这个是比拟好了解的,退出有100条message,它们的offset是从0到99,假如将数据文件分为5段,第一段为0-19,第二段为20-39,顺次类推,每段放在一个独自的数据文件外面,数据文件以该段中最小的offset命名。这样在查找指定offset的Message的时候,用二分查找就能够定位到该Message在哪个段中。

为数据文件建索引

数据文件分段使得能够在一个较小的数据文件中查找对应offset的message了,然而这仍然须要程序扫描能力找到对应offset的message。为了进一步提高查找的效率,Kafka为每个分段后的数据文件建设了索引文件,文件名与数据文件的名字是一样的,只是文件扩大名为.index。

索引文件中蕴含若干个索引条目,每个条目示意数据文件中一条message的索引。索引蕴含两个局部(均为4个字节的数字),别离为绝对offset和position。

  • 绝对offset:因为数据文件分段当前,每个数据文件的起始offset不为0,绝对offset示意这条message绝对于其所属数据文件中最小的offset的大小。举例,分段后的一个数据文件的offset是从20开始,那么offset为25的message在index文件中的绝对offset就是25-20 = 5。存储绝对offset能够减小索引文件占用的空间。
  • position:示意该条message在数据文件中的相对地位。只有关上文件并挪动文件指针到这个position就能够读取对应的message了。

通过offset查找message

假如咱们想读取offset=368776的message(参考第图二)

  1. 查找segment file

00000000000000000000.index示意最开始的文件,起始偏移量(offset)为0.第二个文件00000000000000368769.index的音讯量起始偏移量为368770 = 368769 + 1.同样,第三个文件00000000000000737337.index的起始偏移量为737338=737337 + 1,其余后续文件顺次类推,以起始偏移量命名并排序这些文件,只有依据offset 二分查找文件列表,就能够疾速定位到具体文件。
当offset=368776时定位到00000000000000368769.index|log

  1. 通过segment file查找message

通过第一步定位到segment file,当offset=368776时,顺次定位到00000000000000368769.index的元数据物理地位(依据00000000000000368769.index这个文件是partition里的第几个文件)和00000000000000368769.log的物理偏移地址(依据索引文件里的物理偏移量),而后再通过00000000000000368769.log程序查找直到offset=368776为止。

segment index file并没有为数据文件中的每条message建设索引,而是采取稠密索引存储形式,每隔肯定字节的数据建设一条索引,它缩小了索引文件大小,通过map能够间接内存操作,稠密索引为数据文件的每个对应message设置一个元数据指针,它比浓密索引节俭了更多的存储空间