Kafka - 之kafka为什么这么快(页缓存、零拷贝、顺序写磁盘)!

kafka为什么这么快,主要是得益于以下几点

  • 页缓存(读)
  • 零拷贝(读写)
  • 顺序写磁盘(写)

用户应用与磁盘之间文件之间的读写可以大致分为以下几层分工

###############################
 用户层(服务端应用)
 用户态缓存
###############################
 内核层(操作系统内核)
 页缓存  socket缓存
###############################
    磁盘文件 网卡

1 什么是页缓存

页缓存是Linux内核中的一种重要的高速磁盘缓存,是计算机随机存取器RAM(内核缓存)中的一块区域,主要是负责用户空间磁盘文件之间的高效读写。

具体的整个读写流程如下:

# DMA direct memory access:直接存储器访问,也就是直接访问RAM,不需要依赖CPU的负载
# CPU :中央核心处理器,主要用于计算,如果用于拷贝就太浪费资源
磁盘文件 ==DMAcopy=> 页缓存 ==CPUcopy=> 用户空间缓存 ==CPUcopy=> Socket缓存 ==DMAcopy=>> 网卡

页缓存减少了连续读写磁盘文件的次数,操作系统自动控制文件块的缓存与回收生命周期,用访问RAM的缓存代替访问磁盘区域的机制,增强查询效率。

2 什么是零拷贝?

零拷贝是一种为了解决数据从内核缓存用户缓存的CPU拷贝产生的性能消耗的技术。

原理:当数据从磁盘经过DMA copy到页缓存(内核缓存)后,为了减少CPU拷贝的性能损耗,操作系统会将该内核缓存与用户层进行共享,减少一次CPU copy过程,同时用户层的读写也会直接访问该共享存储,本身由用户层到Socket缓存的数据拷贝过程也变成了从 内核到内核的CPU拷贝过程,更加的快速。

具体的流程如下:

磁盘文件 ==DMAcopy=> 【页缓存并共享作为用户空间缓存】 ==CPUcopy=> Socket缓存 ==DMAcopy=>> 网卡

很明显了拷贝操作都是在内核完成,非常高效。

3 什么是顺序写磁盘

随机写磁盘需要多次寻找磁盘地址,这个过程需要频繁的切换磁道,所以过程比较慢。

顺序写磁盘就是在一个磁道连续的写入,数据都排在一起,分布在连续的磁盘扇区,主需要一次寻址就能找到对应的数据,而kafka本身的数据是不需要删除数据的,是已追加的方式写到磁盘,所以这样就能保证磁盘数据连续紧凑,同时kafka是以segment log flie进行分段存储的,每次访问磁盘文件的时候只需要寻址最后一个segment file的磁盘空间,所以也能够保证写入和读取的效率。