美文网首页
零拷贝技术知多少

零拷贝技术知多少

作者: 越陌先生 | 来源:发表于2019-03-30 15:38 被阅读0次


前言

        日常我们通过客户端向服务器请求数据或服务,服务器端则根据请求作出响应。客户端的不断增长需要服务器有更强的处理数据能力。事实上,客户端数量的增长速度已经远远高于服务器硬件的增加速度,这就很可能引起服务器的重负荷,继而产生性能瓶颈。从操作系统层面讲,服务器处理请求 响应 是一次处理 “读”和“写”过程,数据经过 磁盘-->内核缓冲-->应用程序-->socket缓冲-->网卡-->宽带-->手机客户端呈现到用户面前。

        缓冲区的存在提高了数据的响应速度,但数据的重复流转占用了不必要的CPU性能和内存宽带。零拷贝技术可以解决数据的重复“搬运”问题,更有效的利用系统资源,从而提高服务器性能。

基本介绍

         零拷贝是一种避免零拷贝CPU将数据从一块存储拷贝到另一块存储的技术。数据拷贝对CPU来讲是一种比较简单的任务,如果CPU的大部分时间在处理数据拷贝的任务上,复杂的逻辑处于等待状态,这将造成资源的浪费。

传统拷贝方式

  下图是传统的拷贝方式:

  上面是一个 数据从服务器传输到网上的流程,如web应用程序静态内容展示,视频网站流量,电影网站数据下载等应用场景。 可以看出 传统的拷贝流程 涉及到 两次DMA直接拷贝 和两次 CPU拷贝。 CPU在处理系统进程和应用进程时会进行上下文切换 下图是一个上下文切换的时序图:

总共经历了4次上下文切换:

      1 用户请求读操作  CPU从服务器应用切换到内核

      2 数据从内核缓存返回 CPU从内核缓存切换到服务器应用

      3 数据从应用转出 CPU从应用切换到内核

      4 数据传输到客户端后 服务器应用获得返回 CPU从内核切换到服务器应用

传统的拷贝流程 服务器应用进行了两次没有意义的拷贝和CPU上下文切换,即数据从磁盘拷贝到应用,再从应用拷出去,这样做对意义不大 但对于大数据量的操作 加重了系统负担。下面将介绍的零拷贝 将会解决此问题。

零拷贝方式

        从传统的拷贝方式可以看出 服务器应用只是提供了数据的缓存功能,两次CPU拷贝是多余的,数据可以直接通过内核缓存拷贝到套接字缓存 省去了服务器应用的拷贝流程,如下图所示:

  零拷贝方式是如何实现的呢? 这要借助于 Linux内核系统中的 方法:

  sendfile(socket, file, len)

  其中 socket 是要拷贝的套接字缓存地址,file是磁盘文件地址,len为要拷贝的文件大小

  其中套接字缓存 仅仅保存了 读缓存内存地址 网卡缓存通过获取套接字保存的地址 直接从读缓存拷贝文件数据。

  通过零拷贝 CPU的上下文切换也从传统拷贝的4次降到了2次,即 应用请求 应用-> 系统内核 ,请求返还 系统内核-应用

  大大提升了性能。

  两种拷贝模式 的性能比较 横轴为文件大小 纵轴为拷贝耗时

上面的零拷贝 是基于应用程序不会对 文件数据进行修改的情况下 ,如果要进行数据修改 数据还是要加载到 应用内存空间内, 如果应用程序能够直接操作 操作系统内核数据 则不需要拷贝到应用程序内,在Linux中使用mmp()方式完成应用程序数据直接写入内存。应用程序在调用mmp方法后 数据会先通过 DMA 拷贝到操作系统内核的缓冲区中去,应用程序和操作系统共享内核缓冲区,不需要拷贝 应用程序就可以操作内核缓冲区数据,write 数据完后 内核缓冲区的数据再拷贝到套接字缓冲区,完成拷贝操作

典型应用

操作系统底层的革新和优化会带来上层应用层巨大的提升 进而创造出五颜六色的世界。废话不说 直奔主题

 Java NIO的零拷贝

      接口java.nio.channels.FileChannel.transferTo(long position, long count,WritableByteChannel target)

    使用方法:

//文件输入通道

FileChannel inputFileChannel = getInputFileChannel("Test.dmg");

//文件输出通道

FileChannel outputFileChannel = getOutFileChannel("postManNIO.dmg");

//long totalSize = inputFileChannel.transferTo(0,inputFileChannel.size(),outputFileChannel);

最终调的是FileChannelImpl JNI接口实现:

private native long transferTo0(FileDescriptor var1, long var2, long var4, FileDescriptor var6);

    Netty的零拷贝

      1. FileRegion

          FileRegion 封装了 Java的java.nio.channels.FileChannel.transferTo接口

      2. 应用层的零拷贝CompositeByteBuf

          如果要对多段数据操作 正常情况下会 把多段数据组合到一起 系统开辟块内存空间 放进去再进行操作。CompositeByteBuf 是将多段数据 组合到一起 但是引用的还是原数据段 没有开辟内存空间。

            Netty推荐使用 Upooled.wrappedBuffer(ByteBuffer... buffers) 方法 ,底层还是生成了CompositeByteBuf对象 如图

零拷贝 在互联网、大数据应用中有着广泛的应用,如 Web应用 静态文件,视频网站 流数据 及 软件下载等,开源框架也对零拷贝进行了支持 和扩展 ,原理就是 减少数据的转移环节,提高性能 ,如果有兴趣可以动手写个零拷贝程序实现

结语

      5G时代已经来临,网路的传输速度可能达到 1G每秒的速度,到时候CPU的处理运算速度和处理能力将成为应用的瓶颈,怎样设计一个处理速度快,性能优良的应用架构,开发人员将会面临新的挑战。零拷贝通过减少数据拷贝次数,降低CPU上下文切换的次数 能够有效提升数据的处理速度 从而降低网络延迟 提升网络吞吐。让CPU 、每片内存空间物尽其用 也是每个开发人员面对的问题和挑战 。

参考资料

Zero Copy I: User-Mode Perspective  ----https://www.linuxjournal.com/article/6345

zero copy技术图解  ------https://www.jianshu.com/p/8c6b056f73ce

Linux 中的零拷贝技术  -----https://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy1/index.html

相关文章

  • 零拷贝技术知多少

    前言 日常我们通过客户端向服务器请求数据或服务,服务器端则根据请求作出响应。客户端的不断增长需要服务器有更...

  • 浅析Linux中的零拷贝技术

    本文探讨Linux中主要的几种零拷贝技术以及零拷贝技术适用的场景。为了迅速建立起零拷贝的概念,我们拿一个常用的场景...

  • 零拷贝技术

    前言 从字面意思理解就是数据不需要来回的拷贝,大大提升了系统的性能;这个词我们也经常在java nio,netty...

  • 转载:支撑百万并发的 “零拷贝” 技术,你了解吗?

    转载: 支撑百万并发的 “零拷贝” 技术,你了解吗? 零拷贝(Zero-copy)技术指在计算机执行操作时,CPU...

  • Netty零拷贝

    Netty零拷贝分别用到了 直接内存 Linux零拷贝 Netty内部CompositeByteBuf 三个技术点...

  • linux零拷贝技术

    在看Kafka相关设计时,注意到一个零拷贝技术。对其做一简要介绍: 为什么需要零拷贝技术? 以常见的read 和w...

  • 76 netty零拷贝原理&netty线程模型原理

    1 什么是零拷贝 zery-copy 2,为什么kafka中使用 zery-copy 3, 零拷贝技术实现方案有哪...

  • sendfile“零拷贝”、mmap内存映射、DMA

    KAFKA推送消息用到了sendfile,落盘技术用到了mmap,DMA贯穿其中。 先说说零拷贝 零拷贝并不是不需...

  • Linux 零拷贝技术

    目录 [TOC] 简介 零拷贝(zero-copy)技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器...

  • Kafka的零拷贝技术

    kafka中的消费者在读取服务端的数据时,需要将服务端的磁盘文件通过网络发送到消费者进程,网络发送需要经过几种网络...

网友评论

      本文标题:零拷贝技术知多少

      本文链接:https://www.haomeiwen.com/subject/qotsbqtx.html