iis服务器助手广告
返回顶部
首页 > 资讯 > 操作系统 >Linux零拷贝技术的用法
  • 833
分享到

Linux零拷贝技术的用法

2023-06-05 16:06:34 833人浏览 独家记忆
摘要

这篇文章主要讲解了“linux零拷贝技术的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux零拷贝技术的用法”吧!       1、为什么需

这篇文章主要讲解了“linux零拷贝技术的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux零拷贝技术的用法”吧!

       1、为什么需要零拷贝

  传统的 Linux 系统的标准 I/O 接口(read、write)是基于数据拷贝的,也就是数据都是 copy_to_user 或者 copy_from_user,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能,有数据表明,在Linux内核协议栈中,这个拷贝的耗时甚至占到了数据包整个处理流程的57.1%。

  2、什么是零拷贝

  零拷贝就是这个问题的一个解决方案,通过尽量避免拷贝操作来缓解 CPU 的压力。Linux 下常见的零拷贝技术可以分为两大类:一是针对特定场景,去掉不必要的拷贝;二是去优化整个拷贝的过程。由此看来,零拷贝并没有真正做到“0”拷贝,它更多是一种思想,很多的零拷贝技术都是基于这个思想去做的优化。

  3、零拷贝的几种方法

  (1)原始数据拷贝操作

  在介绍之前,先看看 Linux 原始的数据拷贝操作是怎样的。假如一个应用需要从某个磁盘文件中读取内容通过网络发出去,像这样:

  while((n = read(diskfd, buf, BUF_SIZE)) > 0)

  write(sockfd, buf , n);

  那么整个过程就需要经历:1)read 将数据从磁盘文件通过 DMA 等方式拷贝到内核开辟的缓冲区;2)数据从内核缓冲区复制到用户态缓冲区;3)write 将数据从用户态缓冲区复制到内核协议栈开辟的 Socket 缓冲区;4)数据从 socket 缓冲区通过 DMA 拷贝到网卡上发出去。

  可见,整个过程发生了至少四次数据拷贝,其中两次是 DMA 与硬件通讯来完成,CPU 不直接参与,去掉这两次,仍然有两次 CPU 数据拷贝操作。

  方法一:用户态直接 I/O

  这种方法可以使应用程序或者运行在用户态下的库函数直接访问硬件设备,数据直接跨过内核进行传输,内核在整个数据传输过程除了会进行必要的虚拟存储配置工作之外,不参与其他任何工作,这种方式能够直接绕过内核,极大提高了性能。

  缺陷:

  1)这种方法只能适用于那些不需要内核缓冲区处理的应用程序,这些应用程序通常在进程地址空间有自己的数据缓存机制,称为自缓存应用程序,如数据库管理系统就是一个代表。

  2)这种方法直接操作磁盘 I/O,由于 CPU 和磁盘 I/O 之间的执行时间差距,会造成资源的浪费,解决这个问题需要和异步 I/O 结合使用。

  方法二:mmap

  这种方法,使用 mmap 来代替 read,可以减少一次拷贝操作,如下:

  buf = mmap(diskfd, len);

  write(sockfd, buf, len);

  应用程序调用 mmap ,磁盘文件中的数据通过 DMA 拷贝到内核缓冲区,接着操作系统会将这个缓冲区与应用程序共享,这样就不用往用户空间拷贝。应用程序调用write ,操作系统直接将数据从内核缓冲区拷贝到 socket 缓冲区,最后再通过 DMA 拷贝到网卡发出去。

  缺陷:

  1)mmap 隐藏着一个陷阱,当 mmap 一个文件时,如果这个文件被另一个进程所截获,那么 write 系统调用会因为访问非法地址被 SIGBUS 信号终止,SIGBUS 默认会杀死进程并产生一个 coredump,如果服务器被这样终止了,那损失就可能不小了。

  解决这个问题通常使用文件的租借:首先为文件申请一个租借锁,当其他进程想要截断这个文件时,内核会发送一个实时的 RT_SIGNAL_LEASE 信号,告诉当前进程有进程在试图破坏文件,这样 write 在被 SIGBUS 杀死之前,会被中断,返回已经写入的字节数,并设置 errno 为 success。

  通常的做法是在 mmap 之前加锁,操作完之后解锁:

  方法三:sendfile

  从Linux 2.1版内核开始,Linux引入了sendfile,也能减少一次拷贝。

  #include

  ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

  sendfile 是只发生在内核态的数据传输接口,没有用户态的参与,自然避免了用户态数据拷贝。它指定在 in_fd 和 out_fd 之间传输数据,其中,它规定 in_fd 指向的文件必须是可以 mmap 的,out_fd 必须指向一个套接字,也就是规定数据只能从文件传输到套接字,反之则不行。sendfile 不存在像 mmap 时文件被截获的情况,它自带异常处理机制。

  缺陷:

  1)只能适用于那些不需要用户态处理的应用程序。

  方法四:DMA 辅助的 sendfile

  常规 sendfile 还有一次内核态的拷贝操作,能不能也把这次拷贝给去掉呢?

  答案就是这种 DMA 辅助的 sendfile。

  这种方法借助硬件的帮助,在数据从内核缓冲区到 socket 缓冲区这一步操作上,并不是拷贝数据,而是拷贝缓冲区描述符,待完成后,DMA 引擎直接将数据从内核缓冲区拷贝到协议引擎中去,避免了最后一次拷贝。

  缺陷:

  1)除了3.4 中的缺陷,还需要硬件以及驱动程序支持。

  2)只适用于将数据从文件拷贝到套接字上。

  方法五:splice

  splice 去掉 sendfile 的使用范围限制,可以用于任意两个文件描述符中传输数据。

  #define _GNU_SOURCE

  #include

  ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

  但是 splice 也有局限,它使用了 Linux 的管道缓冲机制,所以,它的两个文件描述符参数中至少有一个必须是管道设备。

  splice 提供了一种流控制的机制,通过预先定义的水印(watermark)来阻塞写请求,有实验表明,利用这种方法将数据从一个磁盘传输到另外一个磁盘会增加 30%-70% 的吞吐量,CPU负责也会减少一半。

  缺陷:

  1)同样只适用于不需要用户态处理的程序

  2)传输描述符至少有一个是管道设备。

  方法六:写时复制

  在某些情况下,内核缓冲区可能被多个进程所共享,如果某个进程想要这个共享区进行 write 操作,由于 write 不提供任何的锁操作,那么就会对共享区中的数据造成破坏,写时复制就是 Linux 引入来保护数据的。

  写时复制,就是当多个进程共享同一块数据时,如果其中一个进程需要对这份数据进行修改,那么就需要将其拷贝到自己的进程地址空间中,这样做并不影响其他进程对这块数据的操作,每个进程要修改的时候才会进行拷贝,所以叫写时拷贝。这种方法在某种程度上能够降低系统开销,如果某个进程永远不会对所访问的数据进行更改,那么也就永远不需要拷贝。

  缺陷:

  需要 MMU 的支持,MMU 需要知道进程地址空间中哪些页面是只读的,当需要往这些页面写数据时,发出一个异常给操作系统内核,内核会分配新的存储空间来供写入的需求。

  方法七:缓冲区共享

  这种方法完全改写 I/O 操作,因为传统 I/O 接口都是基于数据拷贝的,要避免拷贝,就去掉原先的那套接口,重新改写,所以这种方法是比较全面的零拷贝技术,目前比较成熟的一个方案是最先在 Solaris 上实现的 fbuf (Fast Buffer,快速缓冲区)。

  Fbuf 的思想是每个进程都维护着一个缓冲区池,这个缓冲区池能被同时映射到程序地址空间和内核地址空间,内核和用户共享这个缓冲区池,这样就避免了拷贝。

  缺陷:

  1)管理共享缓冲区池需要应用程序、网络软件、以及设备驱动程序之间的紧密合作

  2)改写 api ,尚处于试验阶段。

  (2)高性能网络 I/O 框架——netmap

  Netmap 基于共享内存的思想,是一个高性能收发原始数据包的框架,由Luigi Rizzo 等人开发完成,其包含了内核模块以及用户态库函数。其目标是,不修改现有操作系统软件以及不需要特殊硬件支持,实现用户态和网卡之间数据包的高性能传递。

  在 Netmap 框架下,内核拥有数据包池,发送环\接收环上的数据包不需要动态申请,有数据到达网卡时,当有数据到达后,直接从数据包池中取出一个数据包,然后将数据放入此数据包中,再将数据包的描述符放入接收环中。内核中的数据包池,通过 mmap 技术映射到用户空间。用户态程序最终通过 netmap_if 获取接收发送环 netmap_ring,进行数据包的获取发送。

感谢各位的阅读,以上就是“Linux零拷贝技术的用法”的内容了,经过本文的学习后,相信大家对Linux零拷贝技术的用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Linux零拷贝技术的用法

本文链接: https://www.lsjlt.com/news/243629.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Linux零拷贝技术的用法
    这篇文章主要讲解了“Linux零拷贝技术的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux零拷贝技术的用法”吧!       1、为什么需...
    99+
    2023-06-05
  • 浅谈Linux的零拷贝技术
    前言 在linux系统内部缓存和内存容量都是有限的,更多的数据都是存储在磁盘中。对于Web服务器来说,经常需要从磁盘中读取数据到内存,然后再通过网卡传输给用户: 那么这也算一次I O的过程,都知道IO过程中需要状态的切...
    99+
    2023-04-28
    Linux 零拷贝 零拷贝技术
  • linux下的零拷贝技术介绍
    本篇内容主要讲解“linux下的零拷贝技术介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux下的零拷贝技术介绍”吧!传统的数据传输方式很长一段时间内,数据拷贝的认识仅仅停留在应用程序层...
    99+
    2023-06-13
  • Linux中零拷贝技术是什么
    这篇文章给大家分享的是有关Linux中零拷贝技术是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。引文在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能。这时候服务端的任务是:将...
    99+
    2023-06-15
  • 什么是零拷贝技术
    本篇内容介绍了“什么是零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是零拷贝1、从一个案...
    99+
    2024-04-02
  • kafka零拷贝技术怎么应用
    Kafka零拷贝技术是一种优化技术,可以提高数据传输的效率,减少数据在内存和磁盘之间的拷贝次数。它的应用主要体现在以下几个方面: ...
    99+
    2023-10-27
    kafka
  • golang零拷贝技术怎么使用
    Go语言中的零拷贝技术主要通过使用unsafe.Pointer和reflect.SliceHeader来实现。下面是一个使用零拷贝技...
    99+
    2023-10-23
    golang
  • 零拷贝Zero-Copy技术如何理解
    这篇文章将为大家详细讲解有关零拷贝Zero-Copy技术如何理解,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 1.前言今天和大家一起学习个底层技术点-零拷贝Zero-Copy。L...
    99+
    2023-06-15
  • 怎么理解Netty、Kafka中的零拷贝技术
    本篇内容介绍了“怎么理解Netty、Kafka中的零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • Linux零拷贝怎么实现
    本篇内容介绍了“Linux零拷贝怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引...
    99+
    2023-06-16
  • Linux如何实现写时拷贝技术
    这篇文章主要介绍了Linux如何实现写时拷贝技术,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。COW技术初窥在linux程序中,fork()会产生一个和父进程完全相同的子进程...
    99+
    2023-06-09
  • 在linux系统中实现零拷贝的方法
    在linux系统中实现零拷贝的方法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。什么是Linux系统Linux是一种免费使用和自由传播的类UNIX操作系统,是一...
    99+
    2023-06-07
  • 浅析MMAP零拷贝在RocketMQ中的运用
    什么是零拷贝 零拷贝(英语: Zero-copy)技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省CPU周期和内存...
    99+
    2024-04-02
  • kafka零拷贝的原理是什么
    Kafka的零拷贝(Zero-Copy)原理是通过避免数据在内核态和用户态之间的多次拷贝来提高性能和效率。在传统的网络数据传输过程中...
    99+
    2023-10-21
    kafka
  • C#中深拷贝和浅拷贝的介绍与用法
    一、什么是深拷贝和浅拷贝 对于所有面向对象的语言,复制永远是一个容易引发讨论的题目,C#中也不例外。此类问题在面试中极其容易被问到,我们应该在了解浅拷贝和深拷贝基本概念的基础上,从设...
    99+
    2024-04-02
  • javascript拷贝数组的技巧
    这篇文章主要介绍“javascript拷贝数组的技巧”,在日常操作中,相信很多人在javascript拷贝数组的技巧问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”javasc...
    99+
    2024-04-02
  • python浅拷贝与深拷贝使用方法详解
    目录一、对象赋值二、浅拷贝三、深拷贝四、深入解析浅拷贝和深拷贝在面试和日常的开发中都会经常遇到 我们就从 对象赋值、浅拷贝、深拷贝 三个方面来讲 一、对象赋值 In [1]: lis...
    99+
    2022-11-13
    python浅拷贝与深拷贝 python深拷贝 python浅拷贝
  • Java中深拷贝,浅拷贝与引用拷贝的区别详解
    目录引用拷贝浅拷贝深拷贝小结引用拷贝 引用拷贝: 引用拷贝不会在堆上创建一个新的对象,只 会在栈上生成一个新的引用地址,最终指向依然是堆上的同一个对象。 //实体类 public c...
    99+
    2024-04-02
  • java零拷贝的实现方式是什么
    本篇内容主要讲解“java零拷贝的实现方式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java零拷贝的实现方式是什么”吧!1.什么是零拷贝零拷贝字面上的意思包括两个,“零”和“拷贝”:“...
    99+
    2023-06-29
  • java零拷贝的实现方式有哪些
    Java 的零拷贝(Zero-copy)是指在数据传输过程中,避免将数据从一个缓冲区复制到另一个缓冲区,从而提高数据传输的效率。Ja...
    99+
    2023-09-23
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作