Kafka的零拷贝(zero-copy)技术是 Kafka 性能高的根本所在。
流程步骤:
这个过程涉及到 4 次上下文切换以及 4 次数据的复制,并且有两次复制操作是由 CPU 完成。但是这个过程中,数据完全没有进行变化,仅仅是从磁盘复制到网卡缓冲区。
在这种情况下,如果能够减少用户空间与内核空间之间的切换,即去掉2和3流程,比传统性能高。这样子首先数据被从磁盘读取到 Read Buffer 中,然后再发送到 Socket Buffer,最后才发送到网卡。虽然减少了用户空间和内核空间之间的数据交换,但依然存在多次数据复制。
可以看出性能都消耗在彼此之间的数据复制过程中,那么进一步减少数据的复制过程,或者干脆没有数据复制这一过程,性能会明显增强。这就是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的零拷贝由 FileChannel.transferTo() 方法实现。transferTo() 方法将数据从 FileChannel 对象传送到可写的字节通道(如Socket Channel等)。
https://www.jianshu.com/p/835ec2d4c170
https://blog.csdn.net/lzb348110175/article/details/100853071