kafka 对硬盘的写入的模式是顺序写,而不是随机 I/O。在顺序写的情况下,速度可与内存持平。
同时利用了操作系统的页缓存(Page Cache),数据写入缓存后,立即返回,不需等待数据被持久化到磁盘。然后由操作系统决定何时把 Page Cache 的数据真正写入到磁盘中。
同时利用了 mmap,mmap其实就是把物理上的磁盘文件的一些地址和page cache地址进行一层映射,使得进程像读写硬盘一样读写内存,定时有os帮助我们将数据刷写到磁盘。
在非零拷贝模式下,应用程序想把磁盘数据通过网卡发出去需要以下步骤:
如下图所示:

进行了2次上下文切换和4次系统调用。其实可以省去第 2和 3 步骤,由内核直接读取数据发送到 网卡。
kakfa 在磁盘的文件目录布局是:
主题的日志文件按分区划分为多个文件夹,文件夹命名为-
以(topic-分区号)作为目录,目录下有 .log 和 .index 和 .timeindex 文件,如下所示:
-rw-r--r-- 1 zhangsan admin 72 Oct 24 22:15 00000000000000000014.index
-rw-r--r-- 1 zhangsan admin 41805 Oct 24 22:15 00000000000000000014.log
-rw-r--r-- 1 zhangsan admin 0 Oct 24 22:15 00000000000000000014.timeindex
-rw-r--r-- 1 zhangsan admin 80 Oct 24 22:15 00000000000000000536.index
-rw-r--r-- 1 zhangsan admin 41760 Oct 24 22:15 00000000000000000536.log
-rw-r--r-- 1 zhangsan admin 0 Oct 24 22:15 00000000000000000536.timeindex
文件夹内的日志文件分为多个 segment,每个 segment 包含三个文件:
首先关注一下每个 segment 的命名,文件名称为20位整数,不够用0填充,数字表示当前 log 文件中第一条消息的偏移量。
.indedx 文件产生的规则是,每当 .log 文件中写入了 4kb 的消息,则会在 .index 文件中新增一条记录,.index 里面是一种稀疏的索引。
比如:
offset: 588 position: 4160
offset: 640 position: 8320
offset: 692 position: 12480
offset: 744 position: 16640
offset: 796 position: 20800
假设现在有消费者,需要从 offset 为700的位置消费数据。假设没有索引文件的情况下,需要从 .log 文件的第一行开始依次往下一次遍历查找,性能比较低。
kafka 的做法是:
更多内容,可以点击下面的链接访问我的数字花园:
我的技术数字花园