kafka 有几个重要的概念需要先了解一下

broker:可以理解为kafka 所在的服务器

zookeeper:分布式服务框架在kafka 中的作用主要负责保存topic ,partition 元数据,和对broker 的监控及治理,以及partition 的leader 选举(partition 可以有多个副本,但是只有一个处于工作状态,副本只是负责同步数据,当leader partition 死掉了,会把起作一个副本的partition 升级为leader)

topic:主题,表示消息属于那种主题(可以理解为消息的分类)

partition:分区,从大的概念来说topic 中的消息都是存放在patition 中,一个topic 可以有多个partition,一个partition 可以有多个副本

offset:偏移量,在kafka 中offset 是partition 中消息序列号,可以认为是这个消息的唯一标识

segment:多个大小相等的segment file (段)组成了一个partition。

segment file 是什么?

每个partition 就相当于一个巨型的文件 里面由多个大小相等的segment file小文件组成,但是每个segment file 的消息数量并不一定相等,这种设计方便旧的segment file 快速删除

每个partition 只需支持顺序进行读写即可,segment 的生命周期由服务端配置参数决定

segment file 由2大部分组成,以.index结尾的索引文件,和以.log 结尾的数据文件 ,索引文件和数据文件的名称是一样的只是文件的后缀名不一样

索引文件是一个稀疏文件索引结构:

索引文件中包含若干个索引条目,每个条目表示数据文件中一条Message的索引。索引包含两个部分,分别为相对offset和position。

名词解释

1,相对offset:因为数据文件分段以后,每个数据文件的起始offset不为0,相对offset表示这条Message相对于其所属数据文件中最小的offset的大小。举例,分段后的一个数据文件的offset是从20开始,那么offset为25的Message在index文件中的相对offset就是25-20 = 5。存储相对offset可以减小索引文件占用的空间。
2,position,表示该条Message在数据文件中的绝对位置。只要打开文件并移动文件指针到这个position就可以读取对应的Message了。

数据文件结构定义如下

每条Message包含了以下三个属性:
offset
MessageSize
data
其中offset表示Message在这个partition中的偏移量(注意和索引文件的相对offset 区分),offset不是该Message在partition数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了partition中的一条Message,可以认为offset是partition中Message的id;MessageSize表示消息内容data的大小;data为Message的具体内容。
 

如果要查找一个消息在partition 中offset 为1000 的消息,

1先根据1000 找到所在.index 索引文件(如何找到这个索引文件,二分法,索引文件的命名就是根据offset 来命名的)

2在这个索引文件中根据相对offset 找到对应的最近索引记录,这个记录中有position (message 的物理地址)

3然后根据partition 的offset (注意 不是索引文件的相对offset)找出对应的message