一、背景
Kafka的零拷贝(zero-copy)技术是 Kafka 性能高的根本所在。
二、传统的拷贝过程
流程步骤:
- 操作系统将数据从磁盘文件中读取到内核空间的页面缓存;
- 应用程序将数据从内核空间读入用户空间缓冲区;
- 应用程序将读到数据写回内核空间并放入socket缓冲区;
- 操作系统将数据从socket缓冲区复制到网卡接口,此时数据才能通过网络发送。
这个过程涉及到 4 次上下文切换以及 4 次数据的复制,并且有两次复制操作是由 CPU 完成。但是这个过程中,数据完全没有进行变化,仅仅是从磁盘复制到网卡缓冲区。
在这种情况下,如果能够减少用户空间与内核空间之间的切换,即去掉2和3流程,比传统性能高。这样子首先数据被从磁盘读取到 Read Buffer 中,然后再发送到 Socket Buffer,最后才发送到网卡。虽然减少了用户空间和内核空间之间的数据交换,但依然存在多次数据复制。
可以看出性能都消耗在彼此之间的数据复制过程中,那么进一步减少数据的复制过程,或者干脆没有数据复制这一过程,性能会明显增强。这就是DMA技术了。
三、DMA技术
DMA(Direct Memory Access,直接存储器访问) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于CPU的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。
传统的内存访问,所有的请求都会发送到 CPU ,然后再由 CPU 来完成相关调度工作。当 DMA 技术的出现,数据文件在各个层之间的传输,则可以直接绕过CPU,使得外围设备可以通过DMA控制器直接访问内存。与此同时,CPU可以继续执行程序。
现在电脑中很多硬件都是支持 DMA 技术的,这里面其中就包括我们此处用到的网卡。还有其他硬件也都是支持 DMA 技术的,例如:磁盘、显卡、声卡等其他硬件。
四、零拷贝技术
有了 DMA 技术的,通过网卡直接去访问系统的内存,就可以实现现绝对的零拷贝了。这样就可以最大程度提高传输性能。通过“零拷贝”技术,我们可以去掉那些没必要的数据复制操作, 同时也会减少上下文切换次数。
通过上图可以看到,零拷贝技术只用将磁盘文件的数据复制到页面缓存中一次,然后将数据从页面缓存直接发送到网络中(发送给不同的订阅者时,都可以使用同一个页面缓存),避免了重复复制操作。
如果有5个消费者,传统方式下,数据复制次数为4*5=20次,而使用“零拷贝技术”只需要1 5=6次,一次为从磁盘复制到页面缓存,5次表示5个消费者各自读取一次页面缓存。
五、JAVA零拷贝的实现
Java的零拷贝由 FileChannel.transferTo() 方法实现。transferTo() 方法将数据从 FileChannel 对象传送到可写的字节通道(如Socket Channel等)。
六、参考
https://www.jianshu.com/p/835ec2d4c170
https://blog.csdn.net/lzb348110175/article/details/100853071