操作系统的IO控制

在整个IO控制方式的发展过程中,始终贯穿着这样一条宗旨:即尽量减少主机对IO控制的干预,把主机从繁杂的IO控制事务中解脱出来,以便更多地去完成数据处理任务。为了缓和高速CPU和IO设备低速间的矛盾,现代操作系统使用通道技术,SPOOLING技术,以及缓冲技术可以做到IO操作由特殊的IO处理器(通道)负责执行,只是在IO开始和结束时,调用CPU中断处理,从而使CPU资源不被IO占用,充分发挥了CPU使用效率。

所以下文要讨论的BIO和NIO,从操作系统对设备管理的角度来说,其CPU使用率都是相同的,因为相同操作系统对设备管理和IO控制是相同的。 只是NIO使用的线程少,所以占用的内存少,减轻了系统对上下文切换的开销。


参考:

什么是NIO

In computer science, asynchronous I/O, or non-blocking I/O is a form of input/output processing that permits
other processing to continue before thetransmission
has finished.

Input and output (I/O) operations on a computer can be extremely slow compared to the processing of data. An I/O device can incorporate mechanical devices that must physically move, such as a hard drive seeking a track to read or write; this is often orders
of magnitude
slower than the switching of electric current. For example, during a disk operation that takes ten milliseconds to perform, a processor that is clocked at one gigahertz
could have performed ten million instruction-processing cycles.

参考:

为什么要NIO


为每个客户端分配一个线程进行IO操作的弊端


这种IO模型已经在了几十年了,这种策略下,read和write调用都是堵塞的。它最大的问题就是每个线程都要占用一个完整的栈帧,假设栈帧的空间为2M,那么1G的内存最多服务512个线程,显然和10K有不小差距。当然,由于硬件资源越来越便宜,线程的内存开销可能不会成为瓶颈。但多线程带来的进程切换的开销却有可能长期存在。


每个客户端一个线程


用一个线程服务所有客户端,后端采用NIO,此技术类似于通信的多路复用(Multiplexing) http://en.wikipedia.org/wiki/Multiplexing


所以NIO的主要优势是,其运用内核的IO线程,从而能够以较小的内存占用和较高的CPU使用效率支持大并发访问。此处需要注意的是并不是所有的操作系统就原生支持这种IO策略,例如*nix (Linux, Unix) 就不支持,所以其异步IO(AIO:Asynchronous IO) 其实是通过采用线程池与阻塞IO模拟异步IO,相反,在windows平台下的IOCP,它在某种程度上提供了理想的异步IO:调用异步方法,等待IO完成之后的通知,执行回调,用户无须考虑轮询。其背后原理依然是线程池,不同之处在于这些线程池由系统内核接受管理,所以占用内存小,上下文切换的代价也低。


异步IO带来的性能提升

就像前面关于NIO定义描述的,IO操作占据了程序运行中绝大部分时间,以数据访问所需要的开销为例(p48 NodeJS),访问CPU一级缓存需要3个CPU时钟周期,访问内存需要250个,访问硬盘需要41000000个,而访问网络则需要240000000个时钟周期。

所以异步IO能够带来明显的性能提升,例如一个业务需要执行如下操作

//消费时间为M
getData ('from db')

//消费时间为N
doOperate('from remote API')

如果是同步阻塞IO,其所需时间为M+N, 如果是异步IO,其所需时间为Max(M, N),可见其性能提升是很明显的。

异步IO带来的吞吐量提升

大家都知道建立TCP connection是比较耗时的,如果采用阻塞式的方式,势必会影响服务器的TPS,在我的下一遍关于BIO和NIO的性能分析中,有详细的测试报告,测试结果大概是BIO Accept一个TCP connection的时间大概是NIO的十倍。

我的观点

虽然最近Node和NIO很火,也不就意味着像Apache那种传统的Thread Per Request就到了世界末日了,至少eBay这么大流量的网站,并没有发现Apache Server是性能的瓶颈,瓶颈往往是在数据库上。特别是在Linux系统中,用线程池模拟异步IO,而系统内核又没有原生支持的情况下,我并没有发现其相比较于Apache有什么本质的提升, OK,Node的支持者,也许马上会反驳道,你刚刚不是说数据库是性能瓶颈吗,异步IO可以用异步的方式去访问数据库啊(上面的例子),可以将M+N的时间降低为Max(M,N),这不是性能提升么

事实果真是这样吗?不尽然,因为前后两次操作往往并不是独立的,而是有依赖关系的,也就是说doOperate必须等待getData的结果才能去做,在这种情况下,业务完成时间还是需要M+N。 不过对于网络服务器吞吐量提升和对于大并发的支持,这倒是不争的事实

NIO的缺点是编程过于复杂,如果处理不当,不但不能提高效率,反而会浪费系统资源,综合其优缺点,我个人觉得除非大并发真的变成系统瓶颈,否则最好谨慎使用NIO这把双刃剑


同步和异步IO,阻塞和非阻塞IO:http://www.360doc.com/content/12/0604/15/9579107_215831239.shtml

版权声明:本文为博主原创文章,未经博主允许不得转载。

关于NIO的更多相关文章

  1. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  2. BIO\NIO\AIO记录

    IO操作可以分为3类:同步阻塞(BIO).同步非阻塞(NIO).异步(AIO). 同步阻塞(BIO):在此种方式下,用户线程发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后, ...

  3. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  4. Java I/O and NIO [reproduced]

    Java I/O and NIO.2---Five ways to maximize Java NIO and NIO.2---Build more responsive Java applicati ...

  5. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

  6. Java NIO概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...

  7. JAVA NIO Socket通道

      DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...

  8. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

  9. java nio系列文章

    java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍   (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...

  10. (转)NIO与AIO,同步/异步,阻塞/非阻塞

    原文地址: http://www.cnblogs.com/enjoy-ourselves/p/3793771.html 1.flip(),compact(),与clear()的使用 flip()内部实 ...

随机推荐

  1. 详解c++指针的指针和指针的引用(转)

    http://www.cnblogs.com/li-peng/p/4116349.html

  2. Python基础篇【第5篇】: Python模块基础(一)

    模块 简介 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就 ...

  3. XF 文档 - Element Framework Doc

    配置篇 Chapter Configuration Schema篇 Chapter Schema 查询篇 Chapter Querying Data 数据更改及验证篇 Chapter Data Mod ...

  4. canvas生成二维码,并下载保存为本地的图片

    function getTicket(id,salt){//qrcode生成canvas二维码 $(".zc-mask").show(); $(".edit-box&qu ...

  5. PL/SQL使用技巧

    1.如何在PL/SQL developer中查看所连接的oracle的版本答:select * from v$version;或者在pl/sql developer 里查看[Reports]——> ...

  6. 2.4 ARM寻址方式

    所谓的寻址方式就是处理器指令中给出的信息来找到指令所需要的操作数的方式 1. 立即数寻址 立即数寻址,是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数,这个操作数被称为立即 ...

  7. 数据回复之TestDisk的使用

    1,选择[No Log]或者是[Create]进入 2.选择好要恢复的硬盘,回车 3.选择Intel或者其他的系统,大多数选择intel(windows)使用,回车确认 4.选择[Analyse](分 ...

  8. 小小收获for python

    包导入问题: 包之外导入:还是按照sys.path的搜索路径进行模块的导入 包内的导入:python3.0+     完全区分绝对导入和相对导入 from . import string     #在 ...

  9. 关于处理小数点位数的几个oracle函数

    1. 取四舍五入的几位小数 select round(1.2345, 3) from dual; 结果:1.235 2. 保留两位小数,只舍 select trunc(1.2345, 2) from ...

  10. js 实现动态的图片时钟

    效果如下图 附件有图片   http://files.cnblogs.com/files/biyongyao/时钟.rar 源代码 <!DOCTYPE html> <html> ...