小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
作者:姜太公的语
推荐阅读时间:10分钟
字数:1518字
kafka是什么
官网解释:
Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.
译文:
Apache Kafka 是一个开源分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用程序
一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一。 下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储。
Kafka部分名词解释如下:
- Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
- Topic:可以理解为一个队列,生产者和消费者面向的都是一个topic
- Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。
- Segment:partition物理上由多个segment组成
- offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息.
本文从以下4个步骤进行分析:
- topic中partition存储分布
- partiton中segment文件存储结构
- 在partition中如何通过offset查找message
topic中partition存储分布
在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。
比如笔者在只有一个broker的kafka集群创建了两个topic:first和name,数量都为partitions=2,文件结构如下所示,每一行代表一个文件夹
|--first-0
|--first-1
|--name-0
|--name-1
partiton中segment文件存储结构
每个partiton中都是以一种segment(逻辑概念)存储信息的
- segment file组成:.index文件和.log文件,这两个文件是成对出现的,分别代表索引文件和数据文件
- segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。
此处的index文件和log文件为一个segment,各个segment的大小是相等的,但是消息的数量是不相等的,这样可以快速删除无用文件,有效提高磁盘利用率。
文件结构图:
log/
|--first-0
-- 00000000000000000000.index
-- 00000000000000000000.log
-- 00000000000000737337.index
-- 00000000000000737337.log
...
|--first-1
|--name-0
|--name-1
下图为index文件和log文件的结构示意图
注意: 368769的索引文件是不包含偏移量为368769的信息的
以索引文件中元数据3,497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。
在partition中如何通过offset查找message
例如读取offset=368776的message,需要通过下面2个步骤查找。
- 第一步查找segment file 上述图2为例,其中00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0.第二个文件00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1.同样,第三个文件00000000000000737337.index的起始偏移量为737338=737337 + 1,其他后续文件依次类推,以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。 当offset=368776时定位到00000000000000368769.index
- 第二步通过segment file查找message 通过第一步定位到的segment file,当offset=368776时,依次定位到00000000000000368769.index的元数据(6,1407)物理位置和00000000000000368769.log中(Message368775,1407)的物理偏移地址,然后再通过00000000000000368769.log文件顺序查找直到offset=368776为止。
总的来说就是先从index文件中找到想要找的offect的物理偏移量或者是最近的物理偏移量,然后在log文件中定位找到所需要的数据
从上述图3可知这样做的优点,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间。
扩展:
mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。
本人是该领域的小白,在学习的路上,上述文章如有错误还请指出批评。