零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。
作用
它的作用是在数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现 CPU 的零参与,彻底消除 CPU 在这方面的负载。
实现零拷贝用到的最主要技术是 DMA 数据传输技术和内存区域映射技术:
零拷贝机制可以减少数据在内核缓冲区和用户进程缓冲区之间反复的 I/O 拷贝操作。
零拷贝机制可以减少用户进程地址空间和内核地址空间之间因为上下文切换而带来的 CPU 开销。
基本概念
在 Java NIO 中的通道(Channel)就相当于操作系统的内核空间(kernel space)的缓冲区。
而缓冲区(Buffer)对应的相当于操作系统的用户空间(user space)中的用户缓冲区(user buffer):
通道(Channel)是全双工的(双向传输),它既可能是读缓冲区(read buffer),也可能是网络缓冲区(socket buffer)。
缓冲区(Buffer)分为堆内存(HeapBuffer)和堆外内存(DirectBuffer),这是通过 malloc() 分配出来的用户态内存。
在业务代码的编写中,我们会遵循分层的思想。
前端页面传递一个 Restful,我们在 controller 变为 vo,然后到 service 变为 bean,在数据库操作变为 dao。
每一次都要进行属性的复制。
如果直接从 vo=>入库,可以认为是一种零拷贝。
Linux 系统
传统拷贝
传统的 Linux 操作系统的标准 I/O 接口是基于数据拷贝操作的,即 I/O 操作会导致数据在操作系统内核地址空间的缓冲区和应用程序地址空间定义的缓冲区之间进行传输。
这样做最大的好处是可以减少磁盘 I/O 的操作,因为如果所请求的数据已经存放在操作系统的高速缓冲存储器中,那么就不需要再进行实际的物理磁盘 I/O 操作。
还有另外一种利用预先映射机制的共享缓冲区的方法也可以在应用程序地址空间和操作系统内核之间快速传输数据。
采用缓冲区共享这种思想的架构最先在 Solaris 上实现,该架构使用了“ fbufs ”这个概念。
这种方法需要修改 API。
应用程序地址空间和操作系统内核地址空间之间的数据传递需要严格按照 fbufs 体系结构来实现,操作系统内核之间的通信也是严格按照 fbufs 体系结构来完成的。
每一个应用程序都有一个缓冲区池,这个缓冲区池被同时映射到用户地址空间和内核地址空间,也可以在必要的时候才创建它们。
通过完成一次虚拟存储操作来创建缓冲区,fbufs 可以有效地减少由存储一致性维护所引起的大多数性能问题。
前面提到的几种零拷贝技术都是通过尽量避免用户应用程序和操作系统内核缓冲区之间的数据拷贝来实现的,使用上面那些零拷贝技术的应用程序通常都要局限于某些特殊的情况:要么不能在操作系统内核中处理数据,要么不能在用户地址空间中处理数据。
而这一小节提出的零拷贝技术保留了传统在用户应用程序地址空间和操作系统内核地址空间之间传递数据的技术,但却在传输上进行优化。
我们知道,数据在系统软件和硬件之间的传递可以通过 DMA 传输来提高效率,但是对于用户应用程序和操作系统之间进行数据传输这种情况来说,并没有类似的工具可以使用。
本节介绍的技术就是针对这种情况提出来的。
在介绍直接 I/O 之前,这一小节先介绍一下为什么会出现直接 I/O 这种机制,即传统的 I/O 操作存在哪些缺点。
什么是缓存 I/O (Buffered I/O)
缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。
在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。
缓存 I/O 有以下这些优点:
-
缓存 I/O 使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理设备。
-
缓存 I/O 可以减少读盘的次数,从而提高性能。
DMA 的好处
在介绍DMA之前我想问大家:我们为什么要引入DMA,DMA对我们有什么好处那?
计算机系统中各种常用的数据输入/输出方法有查询方式(包括无条件及条件传送方式)和中断方式,这些方式适用于CPU与慢速及中速外设之间的数据交换。
但当高速外设要与系统内存或者要在系统内存的不同区域之间进行大量数据的快速传送时,就在一定程度上限制了数据传送的速率。
直接存储器存取(DMA)就是为解决这个问题提出的,采用DMA方式,在一定时间段内,由DMA控制器取代CPU,获得总线控制权,来实现内存与外设或者内存的不同区域之间大量数据的快速传送。