java使用原始套接字技术进行数据包截获_Linux零拷贝技术,看完这篇文章就懂了...

2023-11-11

3a22ff8214eaec09d66f9d5837705021.png

本文讲解 Linux 的零拷贝技术,云计算是一门很庞大的技术学科,融合了很多技术,Linux 算是比较基础的技术,所以,学好 Linux 对于云计算的学习会有比较大的帮助。

本文借鉴并总结了几种比较常见的 Linux 下的零拷贝技术,相关的引用链接见文后,大家如果觉得本文总结得太抽象,可以转到链接看详细解释。

为什么需要零拷贝

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

什么是零拷贝

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

a95b49d0059c1da065feb31254de22a0.png

零拷贝的几种方法

原始数据拷贝操作

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

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

write(sockfd, buf , n);

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

c01c609fdb6d8cc0a1c9b7751eb5c05e.png

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

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

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

1000d495a6061f351700346887b17252.png

缺陷:

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 拷贝到网卡发出去。

bbe9b79feb5d8898a910480c2307cd51.png

缺陷:

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 时文件被截获的情况,它自带异常处理机制。

4e4d294f0821e2d6d900f63da381c3a9.png

缺陷:

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

方法四:DMA 辅助的 sendfile

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

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

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

ec6c870370196683b5cdcc1b9b3e4672.png

缺陷:

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

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

方法五:splice

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

#define _GNU_SOURCE         /* See feature_test_macros(7) */

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

ebfb045f328efdac41f81057093bd646.png

缺陷:

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

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

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

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

19770f5fa296fa4017c76e711922a0c9.png

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

总结

1、零拷贝本质上体现了一种优化的思想

2、直接 I/O,mmap,sendfile,DMA sendfile,splice,缓冲区共享,写时复制……

作者:卡巴拉的树
来源:https://www.cnblogs.com/bakari/p/11275735.html

AIOps 风向标!GOPS 2019 · 上海站,汇聚运维行业最佳实践。

38feabd487e176ef97ca87cc01d0e083.png

更多 GOPS 2019 · 上海站精彩,请点击

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java使用原始套接字技术进行数据包截获_Linux零拷贝技术,看完这篇文章就懂了... 的相关文章

  • numpy的两个属性的详解 →→→→arange()和reshape()

    arange 简单的说就是创建了一个数组 print 默认是一维为数组 np arange 5 参数表示从0到5截至 不包括5 print 自定义起点一维数组 np arange 1 5 参数表示从1到5截至 不包括5 print 自定义起
  • mongodb 关于 整数类型 和 字符串类型 索引的比较

    想看看到底是 整数类型的索引快呢 还是字符串类型的索引快 到底快多少呢 内存分别占多少呢 今天就来测试一下 配置 华硕飞行堡垒6 500G 的 SSD 准备数据 a 是 for 循环的变量 id a name abcdefg a 2千万的数
  • python英寸和厘米互换_将厘米转换为英寸的Python程序

    python英寸和厘米互换 There are many problems where we have to calculate the distance in inches at the end but initially the mea
  • Impala链接报错

    impala集成Kerberos链接报错 操作命令 impala shell i 10 250 122 40 19005 k s e3base Error connecting TTransportException Could not s
  • Windows 编程概述(使用 C++)

    Windows 编程概述 使用 C 1 命令行 控制台 应用程序 2 本机桌面客户端应用程序 3 COM 组件 4 通用 Windows 平台应用程序 5 桌面桥 6 游戏 7 SQL Server 数据库客户端 8 Windows设备驱动
  • Qt:QProcess实现cmd命令,带参数.exe程序

    首先引入都文件 include
  • C#系列-set,

    using System public class cls private int book 定义一个域 也可以叫变量 只是面向对像里都这么叫 使用起来也更加方便 public int Book get Console WriteLine
  • DateTimeFormatter、LocalDateTime 的使用

    由于SimpleDateFormat是线程不安全的 所以在多线程中可以使用线程安全的DateTimeFormatter 代替 SimpleDateFormat 阿里巴巴java开发手册推荐 如果是 JDK8 的应用 可以使用 Instant
  • printk,printf 打印调试

    includelinux kernel h define KERN EMERG lt 0 gt 紧急事件消息 系统崩溃之前提示 表示系统不可用 define KERN ALERT lt 1 gt 报告消息 表示必须立即采取措施 define
  • Docker----DockerSwarm集群环境弹性服务动态扩缩容

    详细内容见 DevOps技术社区文章 Docker DockerSwarm集群环境弹性服务动态扩缩容
  • 新词发现

    新词发现是 NLP 的基础任务之一 通过对已有语料进行挖掘 从中识别出新词 新词发现也可称为未登录词识别 严格来讲 新词是指随时代发展而新出现或旧词新用的词语 同时 我认为特定领域的专有名词也可归属于新词的范畴 何出此言呢 通常我们会很容易
  • osgfbo(六)从pass的角度考虑,改写fbo(二)

    什么是pass 这个问题 看似简单 也让我头疼 看了osgdefered pass定义为osg Camera 杨石兴的osg视频教程定义为osg Group 我认为一个passRoot可以定义为一个Group 包含三部分 到目前pass为止
  • RT-Thread Smart 用户态开发体验

    背景 RT Thread Smart 是基于 RT Thread 操作系统上的混合操作系统 它把应用从内核中独立出来 形成独立的用户态应用程序 并具备独立的地址空间 自 V5 0 0 起 rt smart 分支已合并至 master 分支上
  • QT从入门到放弃------制作QT界面

    QT从入门到放弃 一 制作QT界面 创建工程 点击New Project 依次点击下图的Application QT Widgets Application Choose 根据自己的需求选择工程名和存放路径 路径千万不要有中文 路径千万不要
  • QT从入门到实战x篇_01_如何在qtcreator中创建一个程序?(MSVC编译器)

    1 按照如下顺序选择 我这里没有选择console的是因为我只是自己创建界面 不需要控制台的出现 2 命名及选择地址 选择下一步 3 选择基类 是否需要系统自动生成ui文件 基类中有三种选项分别为QWideget QMainWindow Q
  • Linux三级 学习笔记(二)计算机体系结构与操作系统-操作系统

    1 4 操作系统的基本概念 1 4 1 操作系统的定义和作用 操作系统的作用可以从用户和系统俩个不同角度来看 用户视角 系统视角 1 用户视角 操作系统为用户提供的服务有 程序开发 程序运行 I O设备访问 文件访问 系统资源访问 错误检测
  • App 抓包提示网络异常怎么破?

    背景 当你测试 App 的时候 想要通过 Fiddler Charles 等工具抓包看下 https 请求的数据情况 发现大部分的 App 都提示网络异常 无数据等等信息 以 贝壳找房 为例 Fiddler 中看到的请求是这样的 你可能开始
  • 已安装 MySQL,但执行 mysql 命令提示命令找不到!

    因个人需要 在阿里购买了一个轻量应用服务器 服务器配好 LAMP 环境 但奇怪是的我想登录 MySql 却提示命令找不到 查看 MySQL 运行状态 却是 Active running 提交了阿里工单 可是感觉客服是答非所问 我也是很无奈
  • Windows Terminal 和 WSL 安装及配置

    一 打开开发者选项和传递优化 二 在Microsoft Store安装Windows Terminal和Ubuntu子系统 三 配置 Windows Terminal配置 打开settings json配置文件 修改如下 此项用来配置打开W

随机推荐

  • 重磅!瞄准 Web 3.0,谷歌云推出专为区块链服务的 Blockchain Node Engine!

    本文由 Cloud Ace 整理发布 更多内容请访问 Cloud Ace 官网 区块链技术正在为世界各地的消费者和企业带来巨大的创新和价值创造 随着技术变得越来越主流 公司需要可扩展 安全和可持续的基础设施来发展业务并支持他们的网络 谷歌云
  • LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】

    LeetCode 1124 表现良好的最长时间段 哈希表 前缀和 单调栈 题目描述 解题思路一 查字典 cur是当前的前缀和 劳累与不劳累天数之差 向前遍历 有两种情况 情况一 若cur大于0则是 0 i 的劳累与不劳累天数之差一定最大 记
  • Angular知识整合一:Angular中的组件和一些基本概念

    什么是Angular Angular是一个基于TypeScript构建的开发平台 它包括一下三个部分 一个基于组件的库 一组涵盖路由 表单管理 客户端服务端通信等各种功能继承的库 一套开发 构建 测试 更新代码的工具 Angular中的知识
  • matlab练习程序(渲染三原色)

    这里我用的空间是x向右为正 y向下为正 z向屏幕里面为正 相当于标准右手系绕x轴旋转了180度 将三个点光源放在 r 0 3 0 0 5 g 0 3 0 5 cos pi 6 0 5 sin pi 6 b 0 3 0 5 cos pi 6
  • 练习-Java继承和多态之接口

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 题目 任务 编写一个学校接待方面的程序 招待不同身份的人的食宿问题 编程要求 仔细阅读右侧编辑区内给出的代码框架及注释 在 Begin End 中编写一个学校接待方面的程序
  • 什么是电力系统的功率平衡?为什么在任何时候要保持电力系统的功率平衡?

    什么是电力系统的功率平衡 为什么在任何时候要保持电力系统的功率平衡 答 电力系统的功率平衡是指电力有功功率和无功功率的平衡 这种功率平衡也就是电力供需平衡 要求电力系统发送的功率与系统的负荷需要随时保持平衡 电能的一个最重要特点就是不能储存
  • 关于Vue.js中数据模型的绑定以及方法事件的绑定与调用

    在vue js中 我们可以将事件方法写在methods属性中 数据模型在data中定义 Vue的基本结构如下 只写最常用的 将数据与vue实例绑定通过v bind标签 这里绑定的是sourceId这个值 基于vue的双向绑定 如果要取vue
  • 蓝桥杯:整除序列

    整除序列 15分 题目描述 有一个序列 序列的第一个数是 n 后面的每个数是前一个数整除 2 请输出这个序列中值为正数的项 输入格式 输入一行包含一个整数 n 输出格式 输出一行 包含多个整数 相邻的整数之间用一个空格分隔 表示答案 评测用
  • 虚拟环境安装和操作

    文章目录 安装相应库和配置 查看已安装虚拟环境 创建虚拟环境 切换 进入虚拟环境 退出虚拟环境 虚拟环境 linux创建Python虚拟环境及配置 Django Flask项目中如何创建Python虚拟环境呢 汇总 环境迁移 安装相应库和配
  • 攻防世界MISC刷题1-50

    目录 1 ext3 2 base64stego 3 功夫再高也怕菜刀 4 easycap 5 reverseMe 6 Hear with your Eyes 7 What is this 8 normal png 9 something i
  • idea 添加 VUE 的语法支持和开发

    一 VUE的开发分两种 一种是直接在HTML文件中使用 一种是VUE文件的形式开发 1 首先我们先让 HTML 文件支持 VUE 的语法指令提示 2 File gt Setting gt Edit gt Inspections gt htm
  • 父类A a = new 子类B

    父类名 a new 子类名 子类名 b new 子类名 比较上面两种创建实例的区别 a只能调用父类的函数 和子类重写父类的方法 不能调用父类中不存在的子类的函数 因为它没有继承 a是父类的引用 指向了一个子类对象 好处如果一旦发现该B对象无
  • Jetson Orin NX install Fastdeploy

    FastDeploy jetson md at develop PaddlePaddle FastDeploy GitHub sudo apt get install gcc sudo apt get install cmake git c
  • postman-token的作用

    Postman生成的代码中的postman token是什么 What is the postman token in generated code from Postman 这主要用于绕过Chrome 等其他浏览器 中的错误 如果XMLH
  • QEMU/KVM PCI Passthrough(i350) & DPDK 网络性能测试

    QEMU KVM PCI Passthrough i350 DPDK 网络性能测试 硬件要求 CPU必须支持硬件虚拟化 Intel VT d or AMD Vi 和 IOMMU 原图链接 主机配置 设置iommu IOMMU kernel
  • kmp算法(最简单最直观的理解,看完包会)

    本文将以特殊的方式来让人们更好地理解kmp算法 不包括kmp算法的推导 接下来 我们将从朴素算法出发 在这之前 我们先设主串为S 模式串为T 我们要解决的询问是主串中是否包含模式串 即T是否为S的子串 版权声明 本文为原创文章 转载请标明出
  • c++ 继承 学习总结1 继承的基本语法

    前言 继承的作用是减少程序中重复的代码段 如果程序中有很多重复的代码段 可以考虑一下能否使用继承 继承的语法 class 子类 继承方式 父类 include
  • 特征提取-特征工程

    目录 1 定义 2 字典特征提取 3 英文 本特征提取 4 中文 本特征提取 1 定义 将任意数据 如 本或图像 转换为可 于机器学习的数字特征 2 字典特征提取 from sklearn feature extraction import
  • 【算法】树状数组维护总结

    本文仅对树状数组的使用作一个总结 并非讲解 这里的操作都对长度为 n n n 的数组 a a a 进行操作 单点修改 区间查询 暴力做法 修改
  • java使用原始套接字技术进行数据包截获_Linux零拷贝技术,看完这篇文章就懂了...

    本文讲解 Linux 的零拷贝技术 云计算是一门很庞大的技术学科 融合了很多技术 Linux 算是比较基础的技术 所以 学好 Linux 对于云计算的学习会有比较大的帮助 本文借鉴并总结了几种比较常见的 Linux 下的零拷贝技术 相关的引