绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Linux 中的零拷贝技术
2020-05-28 15:06:33

什么是拷贝

要知道零拷贝,需要先知道什么是拷贝。其实这个”拷贝“来自于 Linux 中的标准 I/O 接口的基本数据拷贝的操作,而这一操作会导致数据在操作系统内核地址空间的缓冲区和应用程序地址空间定义的缓冲区之间进行传输。

为什么需要零拷贝

从上图中可以看出,共产生了四次数据拷贝,即使使用了DMA来处理了与硬件的通讯,CPU仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了CPU负担。

在此过程中,我们没有对文件内容做任何修改,那么在内核空间和用户空间来回拷贝数据无疑就是一种浪费,而零拷贝主要就是为了解决这种低效性。

概括来说,原因为以下两点:

  1. 占用了较多的 CPU 时间;
  2. 占用了较多的内存空间。

如何来改进

既然传统的 I/O 操作有性能问题,那么如何改进呢?我们将其定义为“零拷贝技术”。

事实上零拷贝主要指的是避免数据拷贝,而非没有拷贝。大致概括如下:

  • 避免操作系统内核缓冲区之间进行数据拷贝操作。
  • 避免操作系统内核和用户应用程序地址空间这两者之间进行数据拷贝操作。
  • 用户应用程序可以避开操作系统直接访问硬件存储。
  • 数据传输尽量让 DMA 来做。
  • 避免不必要的系统调用和上下文切换。
  • 需要拷贝的数据可以先被缓存起来。
  • 对数据进行处理尽量让硬件来做。

零拷贝技术分类

直接 I/O

应用程序直接访问硬件存储,操作系统内核只是辅助数据传输。

避免内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间的拷贝

mmap()

应用程序调用了 mmap() 之后,数据会先通过 DMA 拷贝到操作系统内核的缓冲区中去。接着,应用程序跟操作系统共享这个缓冲区,这样,操作系统内核和应用程序存储空间就不需要再进行任何的数据拷贝操作。

sendfile()

利用 DMA 引擎将文件中的数据拷贝到操作系统内核缓冲区中,然后数据被拷贝到与 socket 相关的内核缓冲区中去。接下来,DMA 引擎将数据从内核 socket 缓冲区中拷贝到协议引擎中去。

这里还是有一次 CPU 拷贝,怎么把这个也省掉呢?继续看——

带有 DMA 收集拷贝功能的 sendfile()

之前我们是把页缓存的数据拷贝到socket缓存中,实际上,我们仅仅需要把缓冲区描述符传到 socket 缓冲区,再把数据长度传过去,这样 DMA 控制器直接将页缓存中的数据打包发送到网络中就可以了。

上图总结为以下 3 步:

  1. DMA 从拷贝至内核缓冲区
  2. 将数据的位置和长度的信息的描述符增加至内核空间(socket 缓冲区)
  3. DMA 将数据从内核拷贝至协议引擎

splice()

sendfile 利用了Linux提出的管道缓冲区机制,只适用于将数据从文件拷贝到套接字上,有一方必须是管道设备,因而限定了它的使用范围。

对数据在页缓存和用户进程的缓冲区的传输过程进行优化

以上几种零拷贝技术都是减少数据在用户空间和内核空间拷贝技术实现的,但是有些时候,数据必须在用户空间和内核空间之间拷贝。这时候,我们只能针对数据在用户空间和内核空间拷贝的时机上下功夫了。

一般方法有:

  1. 写时复制
  2. 缓冲区共享

这里不再细说,感兴趣的可以阅读后面的参考文章深入了解。

小结

在实际应用中,尽管 sendfile 有一些缺点(比如缺少标准实现等),但依然是一个非常有用的功能。Kafka 的消息消费机制就是使用 sendfile —— 严格来说是通过 Java 的 FileChannel.transferTo 方法来实现的。

参考文章

  1. Linux 中的零拷贝技术,第 1 部分
  2. Linux 中的零拷贝技术,第 2 部分
  3. 浅析Linux中的零拷贝技术

本文于公众号“数据Man”,欢迎关注!

数据Man
分享好友

分享这个小栈给你的朋友们,一起进步吧。

Kafka
创建时间:2020-05-22 09:55:12
Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • ?
    栈主

小栈成员

查看更多
  • wangdabin1216
  • 小雨滴
  • chenglinjava0501
  • 时间不说话
戳我,来吐槽~