Java基础-零拷贝技术应用案例

                                  作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

  零拷贝技术在Hadoop生态圈中很多组件得到应用,典型的比如kafka组件,它就很成功的应用了零拷贝技术,那么究竟什么是零拷贝技术呢?以及零拷贝技术和传统的拷贝技术有什么差异呢?还有零拷贝有什么缺陷呢?接下来,本篇博客会跟你一起验证这些问题!

一.传统拷贝

1>.Java中的传统拷贝

  答:正常拷贝先将文件从磁盘交换到系统(内核)空间,再从内核空间交换到user空间,再从user空间交换到内核空间,最后从内核空间交换到目的缓冲区.。接下里我画一张草图来进行解析说明,如下:

2>.传统拷贝案例展示

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File tcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava2.rar"); traditionalCopy(input,tcOutput);
} public static void traditionalCopy(File input,File output) throws Exception{
long start = System.currentTimeMillis();
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw");
byte[] buf = new byte[1024];
int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
}
rafRead.close();
rafWrite.close();
long end = System.currentTimeMillis();
System.out.println("traditionalCopy 用时为:" + (end - start));
}
} /*
traditionalCopy 用时为:5399
*/

二.零拷贝

1>.什么是零拷贝

  答:零拷贝是直接从磁盘交换到内核空间,从内核空间直接输出到目的缓冲区。接下里我画一张草图来进行解析说明,如下:

2>.零拷贝案例展示

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File zcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava3.rar"); ZeroCopy(input,zcOutput);
} public static void ZeroCopy(File input,File output) throws Exception {
long start = System.currentTimeMillis();
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream(output);
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
ZeroCopy 用时为:588
*/

三.测试零拷贝方式和常规拷贝方式性能对比

   测试零拷贝和传统拷贝的性能我们只需要加一个计时功能即可,具体实现代码如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File tcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava2.rar");
File zcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava3.rar"); traditionalCopy(input,tcOutput);
ZeroCopy(input,zcOutput);
} public static void traditionalCopy(File input,File output) throws Exception{
long start = System.currentTimeMillis();
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw");
byte[] buf = new byte[1024];
int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
}
rafRead.close();
rafWrite.close();
long end = System.currentTimeMillis();
System.out.println("traditionalCopy 用时为:" + (end - start));
} public static void ZeroCopy(File input,File output) throws Exception {
long start = System.currentTimeMillis();
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream(output);
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
traditionalCopy 用时为:5286
ZeroCopy 用时为:1986
*/

   执行以上代码后,需要去响应目录检查是否拷贝成功,验证结果如下:

四.零拷贝细节

1>.Linux中的零拷贝

  零拷贝技术的发展很多样化,现有的零拷贝技术种类也非常多,而当前并没有一个适合于所有场景的零拷贝技术的出现。对于 Linux 来说,现存的零拷贝技术也比较多,这些零拷贝技术大部分存在于不同的 Linux 内核版本,有些旧的技术在不同的 Linux 内核版本间得到了很大的发展或者已经渐渐被新的技术所代替。Linux 中的零拷贝技术主要有下面这几种:

直接 I/O:
  对于这种数据传输方式来说,应用程序可以直接访问硬件存储,操作系统内核只是辅助数据传输:这类零拷贝技术针对的是操作系统内核并不需要对数据进行直接处理的情况,数据可以在应用程序地址空间的缓冲区和磁盘之间直接进行传输,完全不需要 Linux 操作系统内核提供的页缓存的支持。
在数据传输的过程中,避免数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间进行拷贝。
  有的时候,应用程序在数据进行传输的过程中不需要对数据进行访问,那么,将数据从 Linux 的页缓存拷贝到用户进程的缓冲区中就可以完全避免,传输的数据在页缓存中就可以得到处理。在某些特殊的情况下,这种零拷贝技术可以获得较好的性能。Linux 中提供类似的系统调用主要有 mmap(),sendfile() 以及 splice()。
对数据在 Linux 的页缓存和用户进程的缓冲区之间的传输过程进行优化。
  该零拷贝技术侧重于灵活地处理数据在用户进程的缓冲区和操作系统的页缓存之间的拷贝操作。这种方法延续了传统的通信方式,但是更加灵活。在  Linux  中,该方法主要利用了写时复制技术。

2>.零拷贝缺陷

  零拷贝也有自己的缺陷,当它拷贝的文件大于2G时,就无法完整实现拷贝过程!比如你拷贝一个4G文件左右,它最终的结果是只能拷贝2G大小的文件。我测试使用CentOS官方镜像进行拷贝!测试代码如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
RandomAccessFileTest();
ZeroCopy();
} public static void RandomAccessFileTest() throws Exception{
long start = System.currentTimeMillis();
File input = new File("D:\\VMwareworkStation\\ISO\\CentOS-7-x86_64-DVD-1511.iso");
File output = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjie_CentOS7.iso");
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw"); byte[] buf = new byte[1024]; int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
} rafRead.close();
rafWrite.close(); long end = System.currentTimeMillis();
System.out.println("RandomAccessFile 用时为:" + (end - start));
} public static void ZeroCopy() throws Exception {
long start = System.currentTimeMillis(); File input = new File("D:\\VMwareworkStation\\ISO\\CentOS-7-x86_64-DVD-1511.iso") ;
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjie_CentOS7_1.iso");
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
System.out.println(System.currentTimeMillis() - start);
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
RandomAccessFile 用时为:46436
ZeroCopy 用时为:1275 */

  以上代码执行结果如下:(数据并没有完整拷贝!!!)

Java基础-零拷贝技术应用案例的更多相关文章

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

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

  2. Linux 零拷贝技术

    简介 零拷贝(zero-copy)技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器之间不必要的中间拷贝过程,有效地提高通信效率,是设计高速接口通道.实现高速服务器和路由器的关键技术之一. ...

  3. java的零拷贝机制

    转:https://blog.csdn.net/zhouhao88410234/article/details/77574689?fps=1&locationNum=9 为何要懂零拷贝原理?因 ...

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

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

  5. Linux零拷贝技术

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

  6. 操作系统IO之零拷贝技术

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

  7. Linux 中的零拷贝技术,第 2 部分

    技术实现 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.第一部分主要介绍了一些零拷贝技术的相关背景知识,简要概 ...

  8. Linux 中的零拷贝技术,第 1 部分

    概述 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.本文是本系列文章的第一部分,主要是介绍一些零拷贝技术的相关 ...

  9. Linux中的零拷贝技术

    转载:https://www.jianshu.com/p/fad3339e3448 引文## 在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能.这时候服务端的任务是: ...

随机推荐

  1. Dynamics 365 支持使用Web Api 通过名称来检索元数据

    关键检索元数据我在之前的一篇博文中稍有提及,当时是为了取实体的picklist字段的属性,但当时的版本只支持通过metadataid检索,而在365中又增加了名称的检索,方便了很多. 本篇依旧用之前博 ...

  2. 原生 JS 实现手机验证码倒计时

    可以使用 pointer-events 来阻止元素成为鼠标事件的 target.html5 新增操作元素 class 类名的方式 classList. classList 方法 add(value): ...

  3. JavaScript快速入门-ECMAScript本地对象(Date)

    JavaScript中的Date 对象用于处理日期和时间. var myDate=new Date()  #Date 对象会自动把当前日期和时间保存为其初始值. 一.Date对象的方法 方法 示例 n ...

  4. 如何使用URLOS进行docker应用开发

    使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力.在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行的情况下,微服务+Docker的完 ...

  5. 普通程序员看k8s的账户管理

    一.知识准备 ● 账户管理分为:userAccount与serviceAccount ● userAccount:通常是给人设计使用的,并且userAccount不在k8s集群内管理 ● servic ...

  6. Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend

    这题是一个贼搞人的线段树 线段树维护的是 区间和a[i - j] 首先对于update的位置可以二分查找 其次update时候的lazy比较技巧 比如更新的是 l-r段,增加的是c 那么这段的值为: ...

  7. Daily Scrumming* 2015.12.15(Day 7)

    一.团队scrum meeting照片 二.成员工作总结 姓名 任务ID 迁入记录 江昊 任务1036 https://github.com/buaaclubs-team/temp-front/com ...

  8. Linux内核设计与实现 第十八章

    1. 内核调试的难点 重现bug困难 调试风险比较大 定位bug的初始版本困难 2. 内核调试的工具和方法 2.1 输出 LOG 输出LOG不光是内核调试, 即使是在用户态程序的调试中, 也是经常使用 ...

  9. C/C+ 感触

    1.       C/C++语言开发的首选利器- C++Test       以前在windows平台下的开发,使用的框架主要是MFC,以及console工程(基于win32SDK),属于纯C/C++ ...

  10. 构建之法-软件测试+质量保障+稳定和发布阶段+IT行业的创新+人、绩效和职业道德

    第十三章(软件测试) 要知道为什么有软件测试,首先需要知道软件开发,软件开发者一般都很难检查出自己的错误,所以才需要另外一个人测试,所以软件测试就诞生了. 书本介绍了很多测试方法,各有各的优缺点,至于 ...