IO模型--从BIO、NIO、AIO到内核select、poll、epoll剖析

news2024/11/18 1:31:35

IO基本概述

IO的分类

IO 以不同的维度划分,可以被分为多种类型;从工作层面划分成磁盘 IO (本地 IO )和网络 IO; 也从工作模式上划分: BIO、NIO、AIO; 从工作性质上分为阻塞式 IO 与非阻塞式 IO; 从多线程角度也可被分为同步 IO 与异步 IO。

Java中IO的介绍

传统的 java.io 包,它基于流模型实现,提供了最熟知的一些 IO 功能,比如 File 抽象、输入输出流等。交互方式是同步、阻塞的方式。 也把 java.net 下面提供的部分网络 API,比如 Socket、ServerSocket、HttpURLConnection 也归类到同步阻塞 IO 类库,因为 网络通信同样是 IO 行为。    
在 Java 1.4 中引入了 NIO 框架(java.nio 包),提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层的高性能数据操作方式。
在实际面试中,从传统 IO 到 NIO、NIO 2,其中有很多地方可以扩展开来,考察点涉及方方面面,比如:
  1. 基础 API 功能与设计, InputStream/OutputStream 和 Reader/Writer 的关系和区别。
  2. NIO、NIO 2 的基本组成。
  3. 给定场景,分别用不同模型实现,分析 BIO、NIO 等模式的设计和实现原理。
  4. NIO 提供的高性能数据操作方式是基于什么原理,如何使用?

java IO概念

  1. IO 不仅仅是对文件的操作,网络编程中,比如 Socket 通信,都是典型的 IO 操作目标。
  2. 输入流、输出流(InputStream/OutputStream)是用于读取或写入字节的,例如操作图片文件。
  3. 而 Reader/Writer 则是用于操作字符,增加了字符编解码等功能,适用于类似从文件中读取或者写入文本信息。本质上计算机操作的都是字节,不管是网络通信还是文件读取,Reader/Writer 相当于构建了应用逻辑和原始数据之间的桥梁
  4. BufferedOutputStream 等带缓冲区的实现,可以避免频繁的磁盘读写,进而提高 IO 处理效率。这种设计利用了缓冲区,将批量数据进行一次操作,但在使用中千万别忘了 flush。

Java中的BIO、NIO、AIO

BIO 是一个同步阻塞 IO, 阻塞 I/O 难以支持高并发的场景。 NIO是一个 非阻塞 I/O,非阻塞的原因就是基于多路复用机制实现,高并发场景下效率非常高。 AIO是一个异步非阻塞IO,理论上讲, AIO的 吞吐量肯定比NIO的要大;但是实际上AIO的底层实现仍使用epoll,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层,不容易深度优化。

Java BIO

BIO 就是Java的传统 IO 模型,与其相关的实现都位于 java.io 包下,其通信原理是客户端、服务端之间通过 Socket 套接字建立管道连接,然后从管道中获取对应的输入/输出流,最后利用输入/输出流对象实现发送/接收信息。 在基本的 Socket 编程模型中,accept 函数只能在一个监听套接字上监听客户端的连接,recv 函数也只能在一个已连接套接字上,等待客户端发送的请求, 只能处理一个客户端连接。

Java NIO

Java-NIO则是JDK1.4中新引入的API;NIO是一种基于通道、面向缓冲区的IO操作,相较BIO而言,它能够更为高效的对数据进行读写操作,同时与原先的BIO使用方式也大有不同。 Java-NIO 是基于多路复用模型实现的,其中存在 三大核心组成部分:Buffer(缓冲区)、Channel(通道)、Selector(选择器)。 NIO 利用单线程轮询事件的机制,通过高效地定位就绪的 Channel,来决定做什么,仅仅 select 阶段是阻塞的,就可以有效避免大量客户端连接时,频繁线程切换带来的问题,应用的扩展能力有了非常大的提高。

NIO 的主要组成部分:

  1. Buffer,高效的数据容器,除了布尔类型,所有原始数据类型都有相应的 Buffer 实现。
  2. Channel,类似在 Linux 之类操作系统上看到的文件描述符,是 NIO 中被用来支持批量式 IO 操作的一种抽象。File 或 Socket通常被认为是比较高层次的抽象,而 Channel 则是更加操作系统底层的一种抽象,这也使得 NIO 得以充分利用现代操作系统底层机制,获得特定场景的性能优化,例如,DMA(Direct Memory Access)等。不同层次的抽象是相互关联的,可以通过 Socket 获取 Channel,反之亦然。
  3. Selector,是 NIO 实现多路复用的基础,它提供了一种高效的机制,可以检测到注册在 Selector 上的多个 Channel 中,是否有 Channel 处于就绪状态,进而实现了单线程对多 Channel 的高效管理。Selector 同样是基于底层操作系统机制,不同模式、不同版本都存在区别。
缓冲区、通道、选择器三者关系:
简单而言,在这三者之间, Buffer负责存取数据,Channel负责传输数据,而Selector则会决定操作那个通道中的数据。

Java AIO

Java 7 引入 NIO 2 ,增添了一种额外的异步 IO 模式,利用事件和回调,处理 Accept、Read 等操作。 Java-AIO与Java-NIO的主要区别在于:使用异步通道去进行IO操作时,所有操作都为异步非阻塞的,当调用read()/write()/accept()/connect()方法时,本质上都会交由操作系统去完成,比如要接收一个客户端的数据时,操作系统会先将通道中可读的数据先传入read()回调方法指定的缓冲区中,然后再主动通知Java程序去处理。

Redis的网络通信模型

通常系统实现网络通信的基本方法是使用 Socket 编程模型,包括创建 Socket、监听端口、处理连接请求和读写请求。但是,由于基本的 Socket 编程模型一次只能处理一个客户端连接上的请求,所以当要处理高并发请求时,一种方案就是使用多线程,让每个线程负责处理一个客户端的请求。 而 Redis 负责客户端请求解析和处理的线程只有一个,那么如果直接采用基本 Socket 模型,就会影响 Redis 支持高并发的客户端访问。 为了实现高并发的网络通信, Linux提供了 select、poll 和 epoll 三种函数实现多路复用机制,而在 Linux 上运行的 Redis,通常采用 epoll 函数实现多路复用机制进行网络通信。

使用 select 和 poll 机制实现 IO 多路复用

select 函数存在两个设计上的不足:
1)select 函数对单个进程能监听的文件描述符数量是有限制的,它能监听的文件描述符个数由 __FD_SETSIZE 决定,默认值是 1024。
2) 当 select 函数返回后,需要遍历描述符集合,才能找到具体是哪些描述符就绪了。这个遍历过程会产生一定开销,从而降低程序的性能。
为了解决 select 函数受限于 1024 个文件描述符的不足,poll 函数对此做了改进。
和 select 函数相比,poll 函数的改进之处主要就在于,它允许一次监听超过 1024 个文件描述符。但是当调用了 poll 函数后,仍然需要遍历每个文件描述符,检测该描述符是否就绪,然后再进行处理。那么,有没有办法可以避免遍历每个描述符呢?就是接下来

目录

IO基本概述

IO的分类

Java中IO的介绍

java IO概念

Java中的BIO、NIO、AIO

Java BIO

Java NIO

NIO 的主要组成部分:

Java AIO

Redis的网络通信模型

使用 select 和 poll 机制实现 IO 多路复用

使用 epoll 机制实现 IO 多路复用


的 epoll 机制。

使用 epoll 机制实现 IO 多路复用

正是因为 epoll 能自定义监听的描述符数量,以及可以直接返回就绪的描述符,Redis 在设计和实现网络通信框架时,就基于 epoll 机制中的 epoll_create、epoll_ctl 和 epoll_wait 等函数和读写事件,进行了封装开发,实现了用于网络通信的事件驱动框架,从而使得 Redis 虽然是单线程运行,但是仍然能高效应对高并发的客户端访问。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低代码/零代码的快速开发框架

目前国内主流的低代码开发平台有:宜搭、简道云、明道云、云程、氚云、伙伴云、道一云、JEPaaS、华炎魔方、搭搭云、JeecgBoot 、RuoYi等。这些平台各有优劣势,定位也不同,用户可以根据自己需求选择。 一、阿里云宜搭 宜搭是阿里巴巴集团在20…

分布式文件存储Minio学习入门

文章目录一、分布式文件系统应用场景1. Minio介绍Minio优点2. MinIO的基础概念、3. 纠删码ES(Erasure Code)4. 存储形式5. 存储方案二、Docker部署单机Minio三、minio纠删码模式部署四、分布式集群部署分布式存储可靠性常用方法冗余校验分布式Minio优势运行分布式minio使用dock…

如何设置股票接口版交易软件的指标涨跌家数?

如何设置股票接口版交易软件指标涨跌家数?今天小编就以通达信为例给大家介绍一下,很多人其实不知道通达信里面有个很厉害的股票情绪的指标,叫做通达信涨跌家数,打开在通达信软件k线界面,然后输入880005就可以找到了。下…

如何解决 Python 中 TypeError: unhashable type: ‘dict‘ 错误

Python “TypeError: unhashable type: ‘dict’ ” 发生在我们将字典用作另一个字典中的键或用作集合中的元素时。 要解决该错误,需要改用 frozenset,或者在将字典用作键之前将其转换为 JSON 字符串。 当我们将字典用作另一个字典中的键时&#xff0c…

AnlogicFPGA-IO引脚约束设置

(https://www.eefocus.com/article/472120.html此链接是一篇关于XillinxFPGA的IO的状态分析,希望自己也要能了解到AnLogic的IO状态并有对此问题的分析能力) 1、DriveStrength: 驱动强度,即最大能驱动的电流大小(见带负…

Project Caliper:目标是打造最佳VR手柄

一提到Valve Index,人们很快联想到它的五指追踪VR手柄,这款支持手势追踪和体感反馈的高端VR手柄,是市面上最强大的C端VR手柄之一。尽管如此,它依然存在许多缺陷,比如配备的小型摇杆质量不佳、集成式设计不利于维修、人…

算法问题——排序算法问题

摘要 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。一般在面试中最常…

布林线(BOLL)计算公式详解,开口收口代表什么

布林带,英文名称BOLL,是John Bollinger在上世纪八十年代创建的,由中轨、上轨、下轨三条线组成。 一、布林线计算公式详解 布林线中轨是简单移动平均线,一般软件上自带的布林带中轨是20日均线,上轨是中轨加上2个标准差…

Spring 系列之FrameWork

Spring 系列文章 文章目录Spring 系列文章前言一、Spring 介绍二、Spring 架构特征三、Spring 优势四、Spring 体系结构五、IOC 控制反转1. 概念引入2. 原理分析六、Bean 管理1. 介绍2. 管理的内容3. Bean 管理方式1. XML实现DI 赋值2. Bean生命周期1. 测试生命周期2. 后置处理…

RuoYi-Vue搭建(若依)

项目简介 RuoYi-Vue基于SpringBootVue前后端分离的Java快速开发框架1.前端采用Vue、Element UI2.后端采用Spring Boot、Spring Security、Redis & Jwt3.权限认证使用Jwt,支持多终端认证系统4.支持加载动态权限菜单,多方式轻松权限控制5.高效率开发&a…

27岁想转行IT,还来得及吗?

来不来得及不还是看你自身的意愿和条件,这个问题要问你自己吧! 每个人的能力、看法都不同。面对类似的问题,很多人会把侧重点放在IT上,或者27岁上面。那么我们试着换一个方式来问呢:什么时候适合转行,有哪些…

1.PostgreSQL

文章目录LIMITWITH 和RECURSIVEPostgreSQL 约束PostgreSQL AUTO INCREMENT(自动增长)PostgreSQL PRIVILEGES(权限)GRANT语法LIMIT SELECT * FROM COMPANY LIMIT 3 OFFSET 2;WITH 和RECURSIVE WITH RECURSIVE t(a,b) AS (VALUES (…

每日学术速递2.16

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Efficient Teacher: Semi-Supervised Object Detection for YOLOv5 标题:高效教师:YOLOv5 的半监督目标检测 作者:Bowen Xu, Mingtao Chen, Wen…

用ChatGPT来预测2023美国大学生数学建模赛题以及高分攻略

一.2023年美赛 2023年美赛将于2023年2月17-21日举行,将会在北京时间:2023年2月 21日,上午10:00前提交论文。 二.用ChatGPT来预测2023美国大学生数学建模赛题 2.1预测一下会有什么类型的题目 答: 由于我是一个人工…

AcWing语法基础课笔记 第五章 C++中的字符串

第五章 C中的字符串 字符串是计算机与人类沟通的重要手段。 ——闫学灿 字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的数字,二者之间可以相互转化: 常用ASCII值:’A’-‘Z’ 是65~90,’a’-‘z’…

【docker知识】DockerFile语法 2:构造指令

1官方文档:Dockerfile reference | Docker Documentation 一、说明 我们将以HelloWorld案例的方法,由浅入深地理解DockerFile指令,并生成自己的镜像。为了避免冗长的官网文章污染您的视线,这里将重要的,常见的指令…

Springcloud-配置中心config

一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…

【大数据】HADOOP-YARN容量调度器多队列配置详解实战

简介 Capacity调度器具有以下的几个特性&#xff1a; 层次化的队列设计&#xff0c;这种层次化的队列设计保证了子队列可以使用父队列设置的全部资源。这样通过层次化的管理&#xff0c;更容易合理分配和限制资源的使用。容量保证&#xff0c;队列上都会设置一个资源的占比&a…

数据分析与SAS学习笔记4

INPUT语句&#xff1a;格式修饰符&#xff1a; “:” 修饰符。表示从下一个非空格列读入数据&#xff0c;直到:1 遇到再下一个空格列&#xff1b; 2 读到预先定义的变量长度&#xff1b; 3 数据行结束。哪个先出现就在哪儿结束。 “&” 修饰符。表示从下一个非空格列读入…

分享我从功能测试转型到测试开发的真实故事

由于这段时间我面试了很多家公司&#xff0c;也经历了之前公司的不愉快。所以我想写一篇文章来分享一下自己的面试体会。希望能对我在之后的工作或者面试中有一些帮助&#xff0c;也希望能帮助到正在找工作的你。 找工作 我们总是草率地进入一个自己不了解的公司工作&#xf…