<返回更多

零拷贝技术

2022-06-28    开猿节流
加入收藏
零拷贝技术

 

 

知识补充:

1、DMA是直接内存访问(Direct Memory Access 技术,早期 DMA 只存在在主板上,如今由于 I/O 设备越来越多,数据传输的需求也不尽相同,所以每个 I/O 设备里面都有自己的 DMA 控制器。

2、每次系统调用都得先从用户态切换到内核态,等内核完成任务后,再从内核态切换回用户态。

我们都听过 kafka 很快,其中一个原因是 kafka 使用零拷贝。看看从文件中读取数据并通过网络将数据传输到另一个程序的场景,在内部的复制操作,需要在用户模式和内核模式之间进行四次上下文切换,并且进行数据复制四次。

  1. 来自磁盘的数据被复制到内核读取缓冲区中。第一个拷贝由直接内存访问 (DMA) 引擎执行,该引擎从磁盘读取文件内容并将它们存储到内核地址空间缓冲区中。
  2. 从内核缓冲区复制到应用程序读取缓冲区(上下文切换,切换到用户模式)。
  3. 从应用程序缓冲区复制到内核套接字缓冲区并再次将数据放入内核地址空间缓冲区(切换到内核模式)。
  4. 从套接字缓冲区它将复制到网络缓冲区

完成所有四个操作后,它将再次切换到用户模式。

零拷贝技术

 

回顾以上动作,其实发现实际上第二个和第三个数据拷贝是可以避免的。JAVA 类库通过 java.nio.channels 中的 transferTo() 方法在 UNIX 系统上执行零副本,使用零拷贝的应用程序请求内核直接将数据从磁盘文件复制到套接字,而不通过应用程序。零拷贝极大提高了应用程序性能,并减少了内核和用户模式之间的上下文切换次数。

我们看看 transferTo() 是如何复制数据的?

  1. transferTo()方法致使文件内容被 DMA(直接内存访问)引擎复制到读取缓冲区中。
  2. 然后内核将数据复制到套接字关联的内核缓冲区中。
  3. 从套接字缓冲区它将复制到网络缓冲区

这里我们还需要 3 个副本和 2 个上下文切换。

零拷贝技术

 

但当前还没有达到零拷贝,如果底层网卡支持收集操作,可以进一步减少内核重复拷贝数据的操作。在 linux 内核 2.4 及更高版本中,套接字缓冲区描述符支持该场景。

  1. transferTo()方法使 DMA 引擎将文件内容复制到内核缓冲区中。
  2. 没有数据被复制到套接字缓冲区中,相反,只有有关数据位置和长度信息的描述符才会附加到套接字缓冲区。DMA 引擎将数据直接从内核缓冲区传递到网络缓冲区。
零拷贝技术

 


零拷贝技术

 

Kafka 和 Nginx 都有实现零拷贝技术,这将大大提高文件传输的性能。拷贝技术,本质上讲就是通过减少非必要的内存拷贝以及上下文切换,来提高文件在通道间复制速度的一种技术。以本文中的transferTo()方法为例,通过该技术,可以将原来四次内存间拷贝减少成两次,将四次上下文切换减少成两次,大大提高复制的速度。但零拷贝技术并非万能的,它有自己的使用场景,对于将大量数据从一个 I/O 通道复制到另一个通道的情况(例如 Web 服务器),都是合适的。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>