零拷贝(Zero-Copy)

1.背景

现在有这样一个场景,我们需要在本地选择一个文件后,然后上传到网络上。
我们再看看文件的内容数据的具体搬运过程:

你会发现,在整个文件搬运的过程中,发生了多次的数据拷贝上下文转换

4次数据拷贝:

  • 第一次:磁盘文件 -> 内核缓存(内核缓冲区,Page Cache),该过程由DMA负责完成,CPU可以执行其他任务。
  • 第二次:内核缓存 -> 用户缓冲区,该过程由CPU负责完成。
  • 第三次:用户缓冲区 -> 内核缓存,该过程由CPU负责完成。
  • 第四次:内核缓存 -> 网卡的设备缓冲区,该过程由DMA负责完成,CPU可以执行其他任务。

4次上下文转换:
每一次的系统调用均会涉及到两次上下文转换:

  • 第一次:用户发起系统调用,上下文将由用户态 -> 内核态
  • 第二次:系统调用执行完成,上下文将由执行时的环境内核态 -> 用户态

而上面的文件搬运过程用到了readwrite这两个系统调用。

通过上面的分析,不难看出,内核态与用户态的交互部分完全没有存在的必要(前提是你不会对加载进用户缓冲区的数据进行二次加工),因此,我们需要去除掉这部分冗余的交互过程。诺,零拷贝这不就登场了嘛。

2.实现方式

2.1 mmap + write

2.1.1 概述

mmap():一个系统调用函数,该函数会将内核缓冲区中的数据直接映射到用户空间,这样做就省去了 内核缓存 -> 用户缓冲区 这一拷贝过程。
write():在发现所要拷贝的数据是内核缓冲区经mmap直接映射过来的,因此,它将直接对应的内核缓存中拷贝数据到Socket缓冲区,但是此过程需要由CPU负责进行数据的拷贝。

2.2.2 评估

通过将read系统调用替换为mmap系统调用,我们减少了一次由内核缓存 -> 用户缓冲区的拷贝过程,但是,我们的系统调用次数没有减少,因此,这种方式还不是最理想的零拷贝方案。

2.2 sendfile

2.2.1 概述

**sendfile()**:一个系统调用函数,它能够代替前面的read()write()这两个系统调用函数,因此,它能够免去两次上下文切换的开销。同时,它也将内核缓存的数据不经过用户缓冲区而直接拷贝到Socket缓冲区(就本场景而言),因此,也能够免去一次内核缓存 -> 用户缓冲区的拷贝过程。

适用环境:Linux 2.1+

2.2.2 评估

该方案同时免去了一次拷贝过程和两次上下文切换所带来的开销,但是,CPU还是参与了一次内存的拷贝,因此这个方案还不是最优解。

2.3 sendfile + SG-DMA

2.3.1 概述

如果网卡支持SG-DMA(可以通过ethtool -k eth0 | grep scatter-gather指令来查看是否支持SG-DMA),拷贝到内核缓存的数据将不再由CPU拷贝至Socket缓冲区了,而是直接由SG-DMA控制器负责直接拷贝至网卡的缓冲区中。

适用环境:Linux 2.4+

2.3.2 评估

CPU全程没有参与到数据的拷贝过程中来,而且系统调用次数也比最初降低了一半,数据拷贝次数也降低了一半,整体执行效率大致提升了一倍!

3.应用

  • Kafka底层大量调用了Java的NIO中的transferTo方法,而该方法又最终发起了sendfile系统调用(如果运行环境支持的话),因此,Kafka在处理海量数据上快如闪电、所向披靡!
  • NGINX目前也支持配置sendfile

4.注意事项

  • 零拷贝技术要求数据不能进行二次加工,如:压缩数据后发送,这种就不能使用零拷贝技术。
  • 零拷贝技术依赖于PageCache(即内核缓存)。

5.大文件传输

51 背景

大文件传输将不走内核缓存。原因如下:

  1. 大文件会占用较多的Page Cache,会挤占热点小(针对于大文件而言)数据的空间,从而使热点数据的命中率下降。
  2. 大文件缓存在Page Cache中,其本身的命中率也不高。

由于大文件传输不走Page Cache,因此前面所说的零拷贝技术它也就用不了了。

5.2 解决方案

5.2.1 异步I/O + 直接I/O

传统的数据拷贝过程:

采用异步I/O + 直接I/O下的大文件拷贝过程:

你会发现,我们数据的拷贝不再经过中间的Page Cache,因此这种I/O方式不就是我们在文件系统(二)中所谈到的直接I/O吗?
同时,我们用户进程并没有持续等待I/O操作的完成,而是立刻返回,继续执行其他任务,因此,我们也达到了异步I/O的目的。

5.3 评估

综合前面的解决方案,我们有:

  • 对于小文件传输,尽可能地采用零拷贝技术。
  • 对于大文件传输,尽可能地采用异步I/O + 直接I/O的方式进行加速传输。

参考文档

9.1 什么是零拷贝?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331512.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git总结超全版

最近想系统的回顾一下Git的使用,如果只想快速的集成git到idea,可以参考另一篇我的博客中的git部分 目录 版本管理工具简介Git安装与配置Git远程仓库配置 Git常用命令为常用命令配置别名(可选)Git忽略文件.gitignore一些概念*本地仓库操作删除仓库内容 *远…

Wireshark 4.2.5:发现 QUIC 和 VXLAN 协议的新功能

Wireshark 是一种先进且广泛使用的网络协议分析仪,最近发布了新版本 4.2.5,它提供了许多新功能和改进。 Wireshark 4.2.5 发行说明 什么是 Wireshark? Wireshark 是世界上最流行的网络协议分析器。它用于故障排除、分析、开发和教育。 Wiresh…

Elasticsearch 分析器的高级用法一(同义词,高亮搜索)

Elasticsearch 分析器的高级用法一(同义词,高亮搜索) 同义词简介分析使用同义词案例 高亮搜索高亮搜索策略unifiedplainvh 同义词 简介 在搜索场景中,同义词用来处理不同的查询词,有可能是想表达相同的搜索目标。 例…

系统架构师考试(九)

TCP/IP协议族 SMTP是简单邮件传输协议 DNS 域名解析协议 URL - IP,通过URL解析ip是哪一台电脑 DHCP 动态IP地址分配的协议 SNMP 简单网络管理协议 TFTP 简单文件管理协议 ICMP 是网络中差错校验,差错报错的协议 IGMP G是组,组…

Hadoop3:客户端向HDFS写数据流的流程讲解(较枯燥)

一、场景描述 我们登陆HDFS的web端,上传一个大文件。 二、流程图 三、讲解 流程1(Client与NameNode交互) 1、HDFS client创建DistributedFileSystem,通过dfs与NameNode进行2次(一来一回4次)对话&#x…

了解K8s集群kubectl命令进行陈述式资源管理

前言 在 Kubernetes 集群中,通过陈述式和声明式资源管理是确保应用程序高效运行的关键。认识这两种管理方法,能够更好地掌握 Kubernetes 集群的运维和管理。 目录 一、K8s 资源管理操作分类 1. 陈述式 2. 声明式 3. K8s 集群管理常用命令概览 二…

Docker Desktop安装和如何在WSL2中使用Docker

最近在使用WSL的过程中,想使用docker遇到了一些问题,在WSL中安装Linux版本的docker,启动镜像之后不能从Windows机器的端口映射出来,查了一圈之后,发现应该使用Docker Desktop软件,下面是安装和使用的方式 …

2、xss-labs之level2

1、打开页面 2、传入xss代码 payload&#xff1a;<script>alert(xss)</script>&#xff0c;发现返回<script>alert(xss)</script> 3、分析原因 打开f12&#xff0c;没什么发现 看后端源码&#xff0c;在这form表单通过get获取keyword的值赋给$str&am…

基于Keras的手写数字识别(附源码)

目录 引言 为什么要创建虚拟环境&#xff0c;好处在哪里&#xff1f; 源码 我修改的部分 调用本地数据 修改第二层卷积层 引言 本文是博主为了记录一个好的开源代码而写&#xff0c;下面是代码出处&#xff01;强烈建议收藏&#xff01;【深度学习实战—1】&#xff1a…

Spring Web MVC(2)

响应 Http响应的结果可以是数据也可以是静态页面可以针对响应设置状态码 Header信息 返回静态页面注解RestController和Controller 我们创建一个前端页面 package com.example.demo.demos.web.controller;import org.springframework.web.bind.annotation.RequestMapping; i…

Rolla‘s homework:Image Processing with Python Final Project

对比学习Yolo 和 faster rcnn 两种目标检测 要求 Image Processing with Python Final Project Derek TanLoad several useful packages that are used in this notebook:Image Processing with Python Final Project Project Goals: • Gain an understanding of the object …

海康威视硬盘录像机NVR连接公网视频监控平台,注册失败,抓包发现有403 forbidden的问题解决

目录 一、问题描述 二、问题定位 1、查看DVR的配置 2、查看需要使用的端口是否开放 3、查看日志 4、抓包 &#xff08;1&#xff09;找出错误 &#xff08;2&#xff09;查看数据包内容 三、问题分析 1、国标28181中的域的概念 2、域应该如何定义 &#xff08;1&am…

蓝桥杯备赛——DP【python】

一、小明的背包1 试题链接&#xff1a;https://www.lanqiao.cn/problems/1174/learning/ 问题描述 输入实例 5 20 1 6 2 5 3 8 5 15 3 3 输出示例 37 问题分析 这里我们要创建一个DP表&#xff0c;DP&#xff08;i&#xff0c;j&#xff09;表示处理到第i个物品时消耗j体…

STM32学习和实践笔记(30):窗口看门狗(WWDG)实验

1.WWDG介绍 1.1 WWDG简介 上一章我们已经介绍了IWDG&#xff0c;知道它的工作原理就是一个12位递减计数器不断递减计数&#xff0c;当减到0之前还未进行喂狗的话&#xff0c;产生一个MCU复位。 窗口看门狗WWDG其实和独立看门狗类似&#xff0c;它是一个7位递减计数器不断的往…

C语言之指针进阶(3),函数指针

目录 前言&#xff1a; 一、函数指针变量的概念 二、函数指针变量的创建 三、函数指针变量的使用 四、两段特殊代码的理解 五、typedef 六、函数指针数组 总结&#xff1a; 前言&#xff1a; 本文主要讲述C语言指针中的函数指针&#xff0c;包括函数指针变量的概念、创建…

aws msk加密方式和问控制连接方式

msk加密方式 msk提供了两种加密方式 静态加密传输中加密 创建集群时可以指定加密方式&#xff0c;参数如下 aws kafka create-cluster --cluster-name "ExampleClusterName" --broker-node-group-info file://brokernodegroupinfo.json --encryption-info file:/…

【基于springboot+vue的房屋租赁系统】

介绍 本系统是基于springbootvue的房屋租赁系统&#xff0c;数据库为mysql&#xff0c;可用于日常学习和毕设&#xff0c;系统分为管理员、房东、用户&#xff0c;部分截图如下所示&#xff1a; 部分界面截图 用户 管理员 联系我 微信&#xff1a;Zzllh_

Wpf 使用 Prism 实战开发Day24

自定义询问窗口 当需要关闭系统或进行删除数据或进行其他操作的时候&#xff0c;需要询问用户是否要执行对应的操作。那么就需要一个弹窗来给用户进行提示。 一.添加自定义询问窗口视图 (MsgView.xaml) 1.首先&#xff0c;添加一个自定义询问窗口视图 (MsgView.xaml) <Use…

qmt量化教程4----订阅全推数据

文章链接 qmt量化教程4----订阅全推数据 (qq.com) 上次写了订阅单股数据的教程 量化教程3---miniqmt当作第三方库设置&#xff0c;提供源代码 全推就主动推送&#xff0c;当行情有变化就会触发回调函数&#xff0c;推送实时数据&#xff0c;可以理解为数据驱动类型&#xff0…

使用 Flask 和 Celery 构建异步任务处理应用

文章目录 什么是 Flask&#xff1f;什么是 Celery&#xff1f;如何在 Flask 中使用 Celery&#xff1f;步骤 1&#xff1a;安装 Flask 和 Celery步骤 2&#xff1a;创建 Flask 应用程序步骤 3&#xff1a;运行 Celery Worker步骤 4&#xff1a;启动 Flask 应用程序 结论 在构建…