美文网首页
系统层面I/O【原理笔记】

系统层面I/O【原理笔记】

作者: 瓜农老梁 | 来源:发表于2019-12-15 22:20 被阅读0次
    目录
    一、I/O调优的重要性
    二、数据传输过程
       1.磁盘到缓存区运动过程
       2.零字节拷贝
    三、虚拟内存
       1.虚拟内存好处
       2.内存页调度
    四、文件I/O
       1.分页技术操作系统执行I/O的过程
       2.文件锁定
    五、场景回顾
    六、知识来源
    
    一、I/O调优的重要性

    I/O操作比内存中数据处理任务的时间更长,差别以数量级计。

    I:O与CPU时间的比较.png

    第一列为处理一个数据单元所需要的时间,第二列为对该数据单元进行磁盘读写所需要的时间,第三列为每秒能处理的数据单元数,第四列为改变第一列第二列的值所能产生的数据吞吐率的提升。

    图中相对说明:单位处理时间减半,仅能提高吞吐率2.2%,I/O时间减半,吞吐几乎翻倍。

    操作系统移动的是大块数据(缓存区),而java.io类喜欢操作小块数据--单个字节、几行文本,有了NIO就可以轻松把大块数据备份到直接使用的地方(ByteBuffer对象)。

    备注:应该将I/O摆在性能调优的第一位,代码调试放在第二位。

    二、数据传输过程
    1.磁盘到缓存区运动过程

    缓存区如何工作,是所有I/O的基础。输入/输出无非就是把数据移进或移出缓存区。


    第一章 I_O 缓冲区操作简图.jpg

    数据从磁盘向运行中的进程的内存区域移动的过程
    1.进程使用read()系统调用,要求其缓存区被填满
    2.内核随机向磁盘控制硬件发出命令,要求从磁盘读取数据。
    3.磁盘控制器把数据直接写入内核缓存区,这一步通过DMA完成,无需主CPU协助。
    4.一旦磁盘控制器把缓存区装满,内核即把数据从内核空间额临时缓存区拷贝到进程执行read()调用时指定的缓存区。

    用户空间:即常规线程所在区域,非特权区域,不能直接访问设备,JVM即常规线程,驻守于用户空间。
    内核空间:是操作系统所在的区域,特权区域,能与设备控制器进行通信,控制者用户区域空间进程的运行状态等。
    所有的I/O都直接或者间接的通过内核空间。

    第一章 三个缓冲区的发散读操作.jpg

    进程一个系统调用,将一连串缓存区地址传递给操作系统,内核按顺序填充或者排干若干缓冲区,读的时候可以发散到多个用户缓存区,写的时候可以从多个用户缓存区把数据汇聚起来。

    备注:内核试图对数据进行高速缓存或者预读取,所以进程所需要数据可能已经在内核空间里了,已在内核空间的只需要拷贝该数据即可。如果不在内核空间,则进程被挂起,内核将数据读到内存。

    2.零字节拷贝
    传统数据从文件传到套接字的路径
    零字节拷贝传统方式.jpg

    一般的将数据从文件传到套接字的路径:
    1.操作系统将数据从磁盘读到内核空间的页缓存中;
    2.应用将数据从内核空间读到用户空间的缓存中;
    3.应用将用户空间数据写回内存空间的套接字缓存中;
    4.操作系统将数据从套接字缓存写到网卡缓存中,以便将数据经网络发出;
    这里有四次拷贝

    零字节拷贝方式
    零字节拷贝.jpg

    拷贝路径
    1.transferTo() 中文件内容被DMA引擎加载入内核buffer
    2.数据不再被拷入socket buffer被取代的只有descriptor关于位置和长度的信息追加到socket buffer,DMA引擎将数据直接从内核buffer拷贝到网卡缓存
    如果使用sendfile(Java 为: FileChannel.transferTo api),两次拷贝可以被避免:允许操作系统将数据直接从页缓存发送到网络上
    注:DMA(Direct Memory Access,直接内存存取) 传输将数据从一个地址空间复制到另外一个地址空间

    三、虚拟内存
    1.虚拟内存好处

    1.一个或者多个的虚拟地址可以指向同一个物理内存地址
    2.虚拟内存空间可大于实际可用的硬件内存

    下图用户空间和内核空间地址映射到同一个物理内存地址


    第一章 内存空间多重映射.jpg

    把内核空间地址与用户空间的虚拟地址映射到同一个物理地址,可以省去内核与用户空间拷贝;前提条件为:
    1.内核与用户缓存区必须使用相同的页对齐
    2.缓冲区的大小需磁盘控制器块大小(通常512字节)的倍数
    3.内存页的大小总是磁盘块大小的倍数(操作系统把内存地址空间划分为页)
    4.虚拟和物理内存页的大小总是相同

    2.内存页调度

    为了支持寻址空间大于物理内存,虚拟内存需要分页(通常称为交换)。分页区即从物理内存置换出来,存储在磁盘上的内存页面。

    第一章 用于分页区高速缓存的物理内存.jpg

    进程A有5个页面,其中两个装入内存,其余存储于磁盘。

    CPU中包含内存管理单元(MMU),逻辑上位于CPU与物理内存之间,该设备包含虚拟地址向物理内存地址转换的映射信息。

    当不存在与该虚拟页形成有效映射物理内存页,MMU会向CPU提交一个页错误,内核验证页的有效性,内核会安排页面调入操作,把缺失的页面内容读回物理内存,通常此时别的页面会移除内存。

    四、文件I/O
    1.分页技术操作系统执行I/O的过程

    当用户进程请求读取文件数据时,文件系统需要确定数据具体在磁盘什么位置,然后着手把相关磁盘扇区读进内存。

    采用分页技术的操作系统执行I/O的过程:
    1.确定请求数据分布在文件系统的哪些页
    2.在内核空间分配足够的内存页,以容纳文件系统页
    3.在内存页与磁盘的文件系统页之间建立映射
    4.为每个内存页产生页错误
    5.虚拟内存系统俘获页错误,安排页面调入,从磁盘上读取页内容,使页有效。
    6.一旦页面调入操作完成,文件系统即对原始数据进行解析,取得所需文件内容或属性
    信息

    备注:大多数操作系统假设进程会继续读取文件剩余部分,因而会预读额外的文件系统页。如果内存 争用情况不严重,这些文件系统页可能在相当长的时间内继续有效。这样的话,当稍后该文件又被 相同或不同的进程再次打开,可能根本无需访问磁盘。

    2.文件锁定

    文件锁定机制允许一个进程阻止其他进程存取某文件,或限制其存取方式。
    文件锁定有两种方式:共享的和独占的。多个共享锁可同时对同一文件区域发生作用;独占锁
    则不同,它要求相关区域不能有其他锁定在起作用。

    共享锁和独占锁的经典应用:
    共享锁和独占锁的经典应用,是控制最初用于读取的共享文件的更新。某个进程要读取文件, 会先取得该文件或该文件部分区域的共享锁。第二个希望读取相同文件区域的进程也会请求共享锁。两个进程可以并行读取,互不影响。假如有第三个进程要更新该文件,它会请求独占锁。该进程会处于阻滞状态,直到既有锁定(共享的、独占的)全部解除。一旦给予独占锁,其他共享锁的读取进程会处于阻滞状态,直到独占锁解除。

    五、场景回顾

    在RocketMQ创建commitLog文件预热时,写入1G大小的假值(0)的意义。
    使用mmap()内存分配时,只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,进而进入内核空间分配物理内存、更新进程缓存表,最后返回用户空间,恢复进程运行。如果没有这些假值,系统不会实际分配物理内存,防止在写入消息时发生缺页异常。

    RocketMQ存储--映射文件预热【源码笔记】

    六、知识来源

    本文整理自《Java NIO》第一章

    相关文章

      网友评论

          本文标题:系统层面I/O【原理笔记】

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