Posted by lily's blog on May 9, 2025

Kafka为什么这么快

  • 顺序读写
  • 零拷贝
  • 消息压缩
  • 分批发送

顺序读取

零拷贝原理

把磁盘中的某个文件内容发送到远程服务器上 那么它必须要经过几个拷贝的过程:

  1. 从磁盘中读取目标文件内容拷贝到内核缓冲区Read Buffer中。
  2. CPU控制器再把内核缓冲区的数据赋值到用户空间的缓冲区中
  3. 接着在应用程序中,调用write()方法,把用户空间缓冲区中的数据拷贝到内核下的Socket Buffer中。
  4. 最后,把在内核模式下的SocketBuffer中的数据赋值到网卡缓冲区(NIC Buffer)。网卡缓冲区再把数据传输到目标服务器上。 四次拷贝 ![[Pasted image 20241101190407.png]]

所谓零拷贝,并不是完全没有数据赋值,只是相对于用户空间来说,不再需要进行数据拷贝。对于前面说的整个流程来说,零拷贝只是减少了不必要的拷贝次数而已。

零拷贝通过DMA(Direct Memory Access)技术把

  1. 文件内容复制到内核空间中的Read Buffer。
  2. 接着把包含数据位置和长度信息的文件描述符加载到Socket Buffer中DMA引擎直接可以把数据从内核空间中传递给网卡缓冲区(NIC Buffer)。 在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且减少了2次cpu的上下文切换,对于效率有非常大的提高。

在程序中如何实现零拷贝呢?

  • 在Linux中,零拷贝技术依赖于底层的sendfile()方法实现
  • 在Java中,FileChannal.transferTo() 方法的底层实现就是 sendfile() 方法。 ![[Pasted image 20241101190434.png]]