2.2磁盘IO网络IO工作机制

article/2025/11/5 18:06:34

磁盘I/O工作机制:访问文件

在Java中,读 & 写对应了 read() & write() 两个系统调用,但只要系统调用,就会存在内核空间地址用户空间地址切换的问题(操作系统为了保护系统安全,必须将内存空间和用户空间进行隔离),因为数据可能需要从内核空间用户空间复制。

如果遇到了非常耗时的操作,如磁盘I/O,数据得从磁盘–>内核空间–>用户空间,复制了两遍,将会非常缓慢。

因此操作系统在内核空间加入了缓存机制,也就是说:如果用户程序访问的是同一段磁盘地址的数据,将会从上一次在内核空间的缓存中直接取得,这样就只复制了一次。

接下来会介绍几种访问文件的方式:

  1. 标准访问文件方式

    • 当调用read()接口时,操作系统检查在内核的高速缓存中有没有数据,如果有就直接返回;否则从磁盘中读取,然后再缓存在内核中。

    • 当调用write()接口时,数据从用户地址空间–>内核地址空间的缓存中,操作完成。

      至于什么时候写到磁盘,由操作系统决定,除非调用sync同步,强制写入磁盘中。

    用户地址空间
    内核地址空间
    物理磁盘
    应用缓存1
    应用缓存2
    高速页缓存1
    高速页缓存2
    磁盘数据
    read方法
    write方法
  2. 直接I/O方式

    • 程序直接访问磁盘数据,不经过操作系统内核,这样做能够减少一次数据复制。
    • y优点:适用与由程序实现~~(而不是操作系统)~~的数据库管理系统等,因为操作系统不知道应该缓存哪些数据、失效哪些数据,但是程序知道。
    • 缺点:如果访问的数据不在缓存中,那么每次都会直接从磁盘加载,而这种加载相对非常慢,多次之后会变得十分低效。
    用户地址空间
    内核地址空间
    物理磁盘
    应用缓存1
    应用缓存2
    高速页缓存1
    高速页缓存2
    磁盘数据
    read方法
    write方法
  3. 同步访问文件方式

    • 数据的读&写都是同步操作,和标准访问不同的是:只有当数据被成功写到磁盘时,才返回标志给应用程序
    • 性能差,只针对于数据安全性要求高的场景,通常由硬件完成
    用户地址空间
    内核地址空间
    物理磁盘
    应用缓存1
    应用缓存2
    高速页缓存1
    高速页缓存2
    磁盘数据
    read方法
    write方法
  4. 异步访问文件方式

    • 当访问数据的线程发出请求后,线程会接着处理其他事情,而不是阻塞(等待),只有当数据返回时才继续处理后续操作。
    • 能提高程序效率,但不是访问文件的效率
    用户地址空间
    内核地址空间
    物理磁盘
    应用缓存1
    应用缓存2
    高速页缓存1
    高速页缓存2
    磁盘数据
    read方法
    write方法
  5. 内存映射方式

    • 将操作系统内存中的某块区域和磁盘中的文件夹关联,访问内存时转化为访问磁盘文件的某段数据(和直接IO的区别就是这个映射,相当于一个定位,就快的多)
    • 目的是减少数据的复制操作,此时这两个空间的数据都相当于是共享的
    用户地址空间
    内核地址空间
    物理磁盘
    地址映射
    地址映射
    应用缓存1
    应用缓存2
    高速页缓存1
    高速页缓存2
    磁盘数据
    read方法
    write方法

Java序列化&反序列化

​ Java序列化就是将一个对象转化为一串二进制的字节数组,然后通过保存这个字节数组进行持久化。而且达到持久化的目的,必须实现java.io.Serializable接口。

​ Java反序列化就是将字节数组再重新构造成对象。

序例化对象

要序例化一个对象,分如下步骤:

  • 创建某种OutputStream对象,然后将其封装在一个ObjectOutputStream对象内
  • 调用writeObject()即可将对象序列化(对象序列化基于字节,因此使用InputStream和OutputStream继承类层次结构)。

反序列化和序列化过程正好相反,需要将一个InputStream封装在ObjectInputStream内,然后调用readObject()获取一个引用,它指向一个向上转型的Object,所以必须向下转型才能直接设置它们。

对于序列化对象的代码:
public class Serialize implements Serializable {public int num = 1;public long id = 777;public static void main(String[] args) throws IOException {//初始化FileOutputStream fos = new FileOutputStream("filepath");ObjectOutputStream oos = new ObjectOutputStream(fos);//开始干事情Serialize sl = new Serialize();//我自己写的对象oos.writeObject(Serialize);oos.flush();oos.close();}
}

另外,在纯Java环境下,Java序列化能够很好地工作;但是在多语言环境下,会出问题,尽量还是用JSON或XML这些通用的数据结构。

网络I/O工作机制

基础知识

首先你得懂TCP的三次握手和四次挥手,在《计算机网络》中有详细说明,不做过多解释。

要想加速网络的I/O,首先要分析一下影响网络的因素

  • 网络带宽:1s内能传输的最大比特数,平均网络带宽为1.7Mb/s
  • 传输距离:也就是数据要在光纤中走的距离,因为有一个折射率,所以大概只有光速的2/3,比如杭州和青岛的两台机子进行同步操作必定会有一个30ms的延时
  • TCP拥塞控制:详细见《计算机网络》

Java Socket工作机制

Socket 是描述计算机之间完成相互通信一种抽象功能。下面将通过一组比喻&一张图让你了解Socket的工作机制:
在这里插入图片描述

  • 两台主机=两个城市
  • 物理链路=高速通道
  • Socket=交通工具
  • 要交付的数据=要运输的货物
  • 通信协议=交通工具的相关规则(比如说电动车不准上高速[狗头]

大致过程:

主机1的程序A和主机2的程序B通信
通过Socket建立连接
底层TCP/IP协议来建立TCP连接
底层IP协议来寻址网络中的主机

但是一台主机上可能运行着多个应用程序,所以,就要通过 TCP 或 UDP 的地址也就是端口号来指定,端口号又对应一个Socket。这样就可以通过一个 Socket 实例,唯一代表一条通信链路了。下面将具体介绍是如何建立链路的。

建立通信链路

当客户端要与服务端通信:

在客户端

  • 客户端首先要创建一个 Socket 实例,操作系统将为这个 Socket 分配一个端口号(port)
  • 创建一个套接字数据结构,包含本地和远程地址&端口号(这个数据结构将一直保存在系统中直到这个连接关闭)
  • 进行 TCP 的三次握手协议
  • Socket 实例的构造函数正确返回,Socket 实例对象就宣布正式创建完成,否则将抛出 IOException 错误。

在服务端

  • 服务端将创建一个 ServerSocket 实例(比较简单,只要端口号未占用,一般实例创建都会成功)

  • 操作系统也会为 ServerSocket 实例创建一个底层数据结构,包含指定监听的端口号和包含监听地址的通配符(通常情况下都是“*”即监听所有地址)

  • 调用 accept() 方法时,进入阻塞状态,等待客户端的请求。


  • 当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构(包含请求源地址和端口)。

  • 这个数据结构,将会关联到 ServerSocket 实例的一个未完成的连接“数据结构“列表中(注意这时服务端与之对应的 Socket 实例并没有正式创建完成,待三次握手完成后,就会将这个 Socket 实例对应的数据结构从未完成列表中移到已完成列表中)

    所以 ServerSocket 所关联的列表中每个数据结构,都代表与一个客户端的建立的 TCP 连接(无论是否完成)

数据传输

传输数据是我们建立连接的主要目的,如何通过 Socket 传输数据,下面将详细介绍。

  • 当连接已经建立成功,服务端和客户端都会拥有一个 Socket 实例,两边的 Socket 实例都有一个 InputStreamOutputStream,正是通过这两个对象来交换数据。

  • Socket 对象正式创建完毕时,操作系统将会为 InputStreamOutputStream 分别分配一定大小的缓冲区,以便数据的写入和读取

  • 写入端将数据写到 OutputStream 对应的 SendQ 队列中,当队列填满时,数据就将会一起发送,到读取端的InputStreamRecvQ 队列中。(如果这时 RecvQ 已经满了,那么 OutputStreamwrite 方法将会阻塞直到 RecvQ 队列有足够的空间容纳 SendQ 发送的数据)

注意:

  • 这个缓存区的大小&写入端的速度&读取端的速度,非常影响该连接的数据传输效率,所以在写入和读取还要有一个协调的过程
  • 如果两边同时传送数据时可能会产生死锁,在后面 NIO 部分将介绍避免这种情况。

http://chatgpt.dhexx.cn/article/UEPYL7x3.shtml

相关文章

磁盘I/O那些事

背景 计算机硬件性能在过去十年间的发展普遍遵循摩尔定律,通用计算机的CPU主频早已超过3GHz,内存也进入了普及DDR4的时代。然而传统硬盘虽然在存储容量上增长迅速,但是在读写性能上并无明显提升,同时SSD硬盘价格高昂,不…

Linux 磁盘I/O是怎么工作的

文件系统是对存储设备上的文件,进行组织管理的一种机制。而 Linux 在各种文件系统实现上,又抽象了一层虚拟文件系统 VFS,它定义了一组,所有文件系统都支持的,数据结构和标准接口。 这样,对应用程序来说&am…

linux 磁盘io监控

我们在线上linux服务器排查问题时,一般会通过top、free、netstat、df -h等命令排查cpu、内存、网络和磁盘等问题。有的时候我们需要更进一步了解磁盘io的使用情况,那么本文就是重点讲解一下如何查看linux的磁盘io信息的。 一、iostat: 安装…

网络IO与磁盘IO

目录 一.了解IO IO流的分类 IO流的数据来源 1.网络 2.磁盘 3.内存 4.键盘 IO流的原理 二.字节流 1.read方法加缓存数组 2.字节流解决乱码问题 3.缓冲字节流 5.序列化和反序列化 三.字符流 四.网络IO 1.Socket和ServerSocket 2.基于Socket手写实现RPC框架 五.…

网络IO和磁盘IO详解

1. 缓存IO 缓存I/O又被称作标准I/O,大多数文件系统的默认I/O操作都是缓存I/O。在Linux的缓存I/O机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间。 读操作:操作系统检查内核的缓冲区有没…

linux系统资源分析 - 磁盘IO篇

目录 一、理解磁盘IO 二、普通文件IO调度 三、磁盘阵列 四、常用命令 4.1 iostat命令详解 五、综合案例(内存&IO) 一、理解磁盘IO 以超市结账为例,来理解磁盘IO的队列情况(结账付款时间 等待时间 服务时间) 交款总人数(排队的人数多,处理慢…

网络I/O与磁盘I/O

目录 一、同步&异步 阻塞&非阻塞二、网络I/O1. BIO2. NIO3. 多路复用器3.1 select & poll3.2 epoll3.3 Redis的IO多路复用 4. Reactor模型5. Netty 三、磁盘I/O1. 缓存I/O2. Direct I/O3. mmap4. write、flush、fsync 一、同步&异步 阻塞&非阻塞 参考&…

Linux 查看磁盘IO的使用

我们在线上linux服务器排查问题时,一般会通过top、free、netstat、df -h等命令排查cpu、内存、网络和磁盘等问题。有的时候我们需要更进一步了解磁盘io的使用情况,那么本文就是重点讲解一下如何查看linux的磁盘io信息的。 1.iostat: 1.1 命…

磁盘IO和网络IO

4、IO访问方式 4.1 磁盘IO 具体步骤: 当应用程序调用read接口时,操作系统检查内核缓冲区中是否存在需要的数据,如果存在,就直接从内核缓存中直接返回,否则从磁盘中读取,然后缓存至操作系统的缓存中。 当应…

内存与IO,磁盘IO,网络IO

本节主要内容: 系统IO原理:Linux VFS FD pagecache [java] 1文件系统的io 2内存和io关系 3网络io 任何程序都有 0:标准输入 1:标准输出 2:报错输出 /proc/$$进入当前进程目录 $$表示当前bash的pid $BA…

关于 IO、存储、硬盘和文件系统

关于IO、存储、硬盘和文件系统 0.引入1.了解IO1.1.存储器IO1.2.设备IO 2.存储介质和存储类型2.1.内存2.2.硬盘2.3.固态硬盘(SSD)2.4.U盘 3.硬盘的工作原理3.1.磁头3.2.盘片3.3.电动机3.4.硬盘的读写操作 4.文件系统概述4.1.文件系统的类型4.2.文件系统的…

Linux查看与测试磁盘IO性能

1. 查看磁盘 IO 性能 1.1 top 命令 top 命令通过查看 CPU 的 wa% 值来判断当前磁盘 IO 性能,如果这个数值过大,很可能是磁盘 IO 太高了,当然也可能是其他原因,例如网络 IO 过高等。 top命令的其他参数代表的含义详见top命令详解…

Linux 查看磁盘IO

查看命令iostat,# 如果没有 iostat 命令,那么使用 yum install sysstat 进行安装 #间隔1秒,查询10次 iostat -x 1 10 由上图可知,vdb磁盘的 %util【IO】几乎都在100%,原因是频繁的读取数据造成的。 其他字段说明 De…

linux查看磁盘io

iostat -dxk 1 2 iostat iostat,对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。 命令参数说明…

linux查看磁盘IO,网络IO 总结

linux查看磁盘IO,网络 IO可用的命令 1. top 监控整体服务器,cpu,内存,磁盘,网络等 2. dstat -d 查看当前磁盘每秒的读取,写入量,单位K 3. dstat -r 查看当前磁盘随机的读IOPS,…

linux查看磁盘io使用情况

六种方法 top命令、vmstat命令、iostat命令、iotop命令、pt-ioprofile命令、pidstat命令 一、 top命令 top - 11:41:22 up 51 min, 2 users, load average: 0.01, 0.04, 0.01 Tasks: 130 total, 1 running, 129 sleeping, 0 stopped, 0 zombie Cpu(s): 0.2%us, 0.1%sy, 0.0%n…

从磁盘看 IO

计算机上的易失和非易失存储器 常见磁盘可以分为两类:机械磁盘和固态磁盘。 第一类,机械磁盘,也称为硬盘驱动器(Hard Disk Driver),通常缩写为 HDD。机械磁 盘主要由盘片和读写磁头组成,数据就…

硬盘io性能分析

一、磁盘性能主要经常会看磁盘i/o使用率、iops、吞吐量、i/o响应时间等,常用命令sar、iostat、dstat : 1、常用命令:iostat -xm 1 ,单位MB,表示每1秒刷新一次 ----------------- avg-cpu ---------------- %user&…

磁盘IO 基本常识

更多内容,前往 IT-BLOG 计算机硬件性能在过去十年间的发展普遍遵循摩尔定律,通用计算机的 CPU主频早已超过3GHz,内存也进入了普及DDR4的时代。然而传统硬盘虽然在存储容量上增长迅速,但是在读写性能上并无明显提升,同…

【性能测试】系统常用监控- -磁盘IO

性能测试系统常用监控- -磁盘 文章目录 性能测试系统常用监控- -磁盘前言磁盘IO1.常用概念2.磁盘IO性能3.性能指标4.性能分析5.常用分析5. 1 iostat命令解析5.2 查看硬盘类型5.3 查看磁盘IO调度5.4 查看磁盘IO调度5.3 调优方法5.1 RAID 总结 前言 性能测试过程中,在…