零拷贝的性能差异
先来有个直观的数据展示下,零拷贝相比传统的数据拷贝能有多大的差别,这一组数据,是我在我的笔记本电脑上测试后对比。
测试的源码地址:
zero测试的代码:
https://github.com/kkzfl22/demojava8/tree/master/src/main/java/com/liujun/network/zerocopy/
零拷贝数据的操作过程
通过数据与图表的观察发现,性能测试的差异有至少3倍之多,为什么零拷贝技术可以提升这么多呢?
这个问题得从数据拷贝的操作讲起:
先写两行伪代码
File.read(fileDesc, buf, len); Socket.send(socket, buf, len); |
这是一个读取本地文件然后发送到远程服务器的伪代码,这一过程一共发生了4次数据拷贝,那为什么是4次呢?
第一次传输,是从硬盘读取到操作系统的内核缓冲区中,这一过程由专用的DMA芯片负责搬运。
第二次传输,是从内核的缓冲区,将数据从内核的缓冲区拷贝到应用程序的内存中,这一过程由CPU负责搬运。
第三次传输,是应用程序将数据拷贝socket的缓冲区中,这一过程由CPU完成数据搬运。
第四次传输,是将socket的缓冲区中的数据写入到网卡的缓冲区,这一过程又是通过DMA芯片来完成的。
就这样完成一次数据的传输,同一份数据一共被拷贝了4次,这是导致效率低下的主要原因。
重点来了,零拷贝
那什么是零拷贝呢?
零拷贝就是不再需要将数据在操作系统内核与应用程序之间进行拷贝。
那不拷贝数据了,如何进行数据的传输?
第一次,数据从硬盘拷贝到操作系统的内核缓冲区中。由DMA芯片来完成。
第二次,根据socket描述符信息,直接将内核缓冲区中的信息,写入到网卡的缓冲区。还是由DMA芯片来完成。
在这个操作的过程中,没有内存层面的数据复制,所以又叫零拷贝。
关于零拷贝更多的内容,可以参看此文
DMA技术(Direct Memory Access)与DMAC(协处理器芯片)
理解了零拷贝的过程,再来认识下DMA芯片
本质上,DMA技术就是在主板上放一块独立的芯片,在进行内存与I/O设备的数据传输的时候,不再通过CPU来控制数据传输,而直接通过DMA控制器(DMA Controller简称DMAC),这块芯片就是协处理器。
DMAC最有价值的地方在于,当传输的数据量特别大时,速度特别快时,又或者数据量特别小,又特别慢时。
来举两个常用的场景吧:
- 如果经传输几部高清电影,这个时候数据量就会我特别的大,选择CPU来操作,CPU肯定会非常的忙,可以选择DMAC。
- 假如现在是需要传输的是手机聊天的消息,这数据量是非常的小,由于手机网络的原因,消息非常的慢,可以选择DMAC,当消息收到完成后再交给CPU来处理。而不用让CPU处于傻等的状态。
优劣势:
优势:零拷贝不需要内存层面的数据复制,将数据发送中的4个复制缩减到2个,在简单的数据传输通道类的应用中,发送具有非常好的性能,至少将传输的性能提供3倍以上,最典型的例子就是kafka。
劣势:同样的零拷贝由于不再需要将数据在操作系统内核与应用程序间拷贝数据,对于读取的数据修改成为问题。不过也有变通办法,那就是预先将数据处理完成,写入到文件中,运行时仅读取文件发送,但对于复杂的数据存储发送类应用,场景还是存在着问题,也需要具体问题具体分析。
总结:
零拷贝技术是一种高效的数据传输通道类技术,它比起常用的数据传输技术,提升性能有至少3倍之多,但没有完美的技术,只有适用的场景,零拷贝技术只能进行数据的传输,在传输过程中应用程序不能对数据内容有任何的修改,这也意味着,它的应用只能在传输技术中。