Kafka为什么这么快
- 顺序读写
- 零拷贝
- 消息压缩
- 分批发送
顺序读取
零拷贝原理
把磁盘中的某个文件内容发送到远程服务器上 那么它必须要经过几个拷贝的过程:
- 从磁盘中读取目标文件内容拷贝到内核缓冲区Read Buffer中。
- CPU控制器再把内核缓冲区的数据赋值到用户空间的缓冲区中
- 接着在应用程序中,调用
write()
方法,把用户空间缓冲区中的数据拷贝到内核下的Socket Buffer中。 - 最后,把在内核模式下的SocketBuffer中的数据赋值到网卡缓冲区(NIC Buffer)。网卡缓冲区再把数据传输到目标服务器上。 四次拷贝 ![[Pasted image 20241101190407.png]]
所谓零拷贝,并不是完全没有数据赋值,只是相对于用户空间来说,不再需要进行数据拷贝。对于前面说的整个流程来说,零拷贝只是减少了不必要的拷贝次数而已。
零拷贝通过DMA(Direct Memory Access)技术把
- 文件内容复制到内核空间中的Read Buffer。
- 接着把包含数据位置和长度信息的文件描述符加载到Socket Buffer中,DMA引擎直接可以把数据从内核空间中传递给网卡缓冲区(NIC Buffer)。 在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且减少了2次cpu的上下文切换,对于效率有非常大的提高。
在程序中如何实现零拷贝呢?
- 在Linux中,零拷贝技术依赖于底层的sendfile()方法实现
- 在Java中,FileChannal.transferTo() 方法的底层实现就是 sendfile() 方法。 ![[Pasted image 20241101190434.png]]