Netty 零拷贝(一)Linux 零拷贝

本文探讨 Linux 中主要的几种零拷贝技术以及零拷贝技术适用的场景。

一、几个重要的概念

1.1 用户空间与内核空间

操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核 (kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。

1.2 IO 两个流程

网络 IO 的本质是 socket 的读取,socket 在 linux 系统被抽象为流,IO 可以理解为对流的操作。刚才说了,对于一次 IO 访问 (以 read 举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说,当一个 read 操作发生时,它会经历两个阶段:

  • 第一阶段:等待网络上的数据分组到达,然后被复制到内核的某个缓冲区 (Waiting for the data to be ready)。
  • 第二阶段:把数据从内核缓冲区复制到应用进程缓冲区 (Copying the data from the kernel to the process)。

本文关注的是第二个过程:如何减少拷贝,即零拷贝。

二、传统的 IO 流程

Linux 的 I/O 操作默认是缓冲 I/O。使用了 read 和 write 两个系统调用,我们并不知道操作系统在其中做了什么。实际上在以上 I/O 操作中,发生了多次的数据拷贝。

当应用程序访问某块数据时,操作系统首先会检查,是不是最近访问过此文件,文件内容是否缓存在内核缓冲区,如果是,操作系统则直接根据 read 系统调用提供的 buf 地址,将内核缓冲区的内容拷贝到 buf 所指定的用户空间缓冲区中去。如果不是,操作系统则首先将磁盘上的数据拷贝的内核缓冲区,这一步目前主要依靠 DMA 来传输,然后再把内核缓冲区上的内容拷贝到用户缓冲区中。
接下来,write 系统调用再把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后 socket 再把内核缓冲区的内容发送到网卡上。

整个过程中共产生了多次数据拷贝,即使用了 DMA 来处理了与硬件的通讯,用户空间和系统空间 CPU 仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了 4 次上下文切换,无疑也加重了 CPU 负担。

  1. 通过 DMA copy 数据从 hard drive 拷贝到 kernel buffer
  2. 通过 CPU copy 数据从 kernel buffer 拷贝到 user buffer
  3. 通过 CPU copy 数据从 user buffer 拷贝到 kernel buffer
  4. 通过 CPU copy 数据从 kernel buffer 拷贝到 socket buffer
  5. 通过 DMA copy 将 socket buffer 中的数据发送出去

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

三、零拷贝(zero-copy)

3.1 零拷贝概念

零拷贝主要的任务就是避免 CPU 将数据从一块存储拷贝到另外一块存储,主要就是利用各种零拷贝技术,避免让 CPU 做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让 CPU 解脱出来专注于别的任务。这样就可以让系统资源的利用更加有效。

如何减少数据拷贝的次数呢?一个很明显的着力点就是减少数据在内核空间和用户空间来回拷贝,这也引入了零拷贝的一个类型:减少用户空间到内核空间的拷贝。

2.2 减少用户空间和内核空间的拷贝

应用程序调用 sendfile,磁盘上的数据会通过 DMA 被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用 write(),操作系统直接将内核缓冲区的内容拷贝到 socket 缓冲区中,这一切都发生在内核态,最后,socket 缓冲区再把数据发到网卡去。

目前为止,我们已经减少了数据拷贝的次数,但是仍然存在一次拷贝,就是页缓存到 socket 缓存的拷贝。那么能不能把这个拷贝也省略呢?

2.3 直接传递文件描述符

在上一种方案中是将页缓存的数据拷贝到 socket 缓存中,实际上,我们仅仅需要把缓冲区描述符传到 socket 缓冲区,再把数据长度传过去,这样 DMA 控制器直接将页缓存中的数据打包发送到网络中就可以了。不过这种收集拷贝功能是需要硬件以及驱动程序支持的。

在服务端响应客户端的场景中,如果使用非直接缓冲区第一步就需要将响应的数据从 JVM 内存拷贝到系统内核中再发送,而使用直接缓冲区就可以省略这个步骤,这就是 零拷贝

四、总结

传统的 IO 读和写都需要在操作系统内核和用户空间之间拷贝,Linus 优化了内核空间和用户空间的拷贝过程,内核空间也可以通过传递文件描述符进一步减少内核中的一次拷贝过程。Linux 零拷贝演进过程:


每天用心记录一点点。内容也许不重要,但习惯很重要!

Netty 零拷贝(一)Linux 零拷贝的更多相关文章

  1. Linux、JDK、Netty中的NIO与零拷贝

    一.先理解内核空间与用户空间 Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应着下图中, CPU 特权等级分为4个,Linux 使用 Ring 0 和 Ring 3. 内核空 ...

  2. NIO学习笔记,从Linux IO演化模型到Netty—— Linux零拷贝

    这里只是感性地认识Linux零拷贝,不涉及具体细节. 1.Linux传统的数据拷贝 用户进程是不能直接访问文件系统的,要先切换到内核态,发起系统调用,DMA把磁盘中的数据写入内核空间,内核再把数据拷贝 ...

  3. 框架篇:Linux零拷贝机制和FileChannel

    前言 大白话解释,零拷贝就是没有把数据从一个存储区域拷贝到另一个存储区域.但是没有数据的复制,怎么可能实现数据的传输呢?其实我们在java NIO.netty.kafka遇到的零拷贝,并不是不复制数据 ...

  4. 【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析

    零拷贝Zero-Copy 我们先来看下它的定义: "Zero-copy" describes computer operations in which the CPU does n ...

  5. Linux零拷贝技术,看完这篇文章就懂了

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 本文讲解 ...

  6. Linux零拷贝技术 直接 io

    Linux零拷贝技术 .https://kknews.cc/code/2yeazxe.html   https://zhuanlan.zhihu.com/p/76640160 https://clou ...

  7. Linux零拷贝技术

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

  8. Linux零拷贝原理

    Linux零拷贝原理 前言 磁盘可以说是计算机系统最慢的硬件之一,读写速度相差内存 10 倍以上,所以针对优化磁盘的技术非常的多,比如零拷贝.直接 I/O.异步 I/O 等等,这些优化的目的就是为了提 ...

  9. 将文件从一台linux机器拷贝到多台的方法

    首先你所操作的各台linux机器间必须设置了ssh免密码登录,具体方法可上网查看.将文件从一台linux机器拷贝到多台分为以下几个步骤: 第一步:创建脚本文件remotecopy.sh #!/bin/ ...

随机推荐

  1. Pillow 读取图片截断错误

    做图像处理的时候,Pillow是经常使用到的模块. 最近在读取图片的时候出现了一个错误. OSError: image file is truncated (461 bytes not process ...

  2. 动态html处理和及其图像识别

    爬虫(Spider),反爬虫(Anti-Spider),反反爬虫(Anti-Anti-Spider) 之间恢宏壮阔的斗争... Day 1 小莫想要某站上所有的电影,写了标准的爬虫(基于HttpCli ...

  3. centos73下php5.6安装GD库

    yum --enablerepo=remi-php56 install php-gd php-mysql php-mbstring php-xml php-mcrypt YUM安装的 找到了源  分分 ...

  4. 8.rem适配

    <!DOCTYPE html> <!--lang="en" : 英语 :声明当前页面的语言类型.--> <html lang="en&quo ...

  5. js运动框架逐渐递进版

    运动,其实就是在一段时间内改变left.right.width.height.opactiy的值,到达目的地之后停止. 现在按照以下步骤来进行我们的运动框架的封装: 匀速运动. 缓冲运动. 多物体运动 ...

  6. centos7配置yum源

    https://www.cnblogs.com/renpingsheng/p/7845096.html

  7. 第二次安装docker时,报Transaction check error的解决方法

    如果在yum安装软件的时候,出现了Transaction check error:这种情况,说明rpm软件包出现了冲突,解决方法是: vi /etc/yum.repos.d/epel.repo 将en ...

  8. Flume环境搭建_五种案例(转)

    Flume环境搭建_五种案例 http://flume.apache.org/FlumeUserGuide.html A simple example Here, we give an example ...

  9. Python 3 学习笔记(1)

    Python 3.6 运算符 + - * / 四则运算 % 求余 **乘方 // 用于整除 字符串 字符串用单引号或双引号括起来. 三引号(单引号或双引号均可)表示多行字符串,行末加反斜杠表示换行不算 ...

  10. 迷你MVVM框架 avalonjs 学习教程22、avalon性能大揭密

    avalon之所以能在页面处理1W个绑定(angular对应的数字是2000),出于两个重要设计--基于事件驱动的双向绑定链及智能CG回收机制. avalon的双向绑定链是通过Object.defin ...