前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系统层面I/O【原理笔记】

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

作者头像
瓜农老梁
发布2019-12-24 16:18:11
4600
发布2019-12-24 16:18:11
举报
文章被收录于专栏:瓜农老梁

目录

一、I/O调优的重要性 二、数据传输过程 1.磁盘到缓存区运动过程

2.零字节拷贝 三、虚拟内存

1.虚拟内存好处

2.内存页调度

四、文件I/O

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

2.文件锁定

五、场景回顾

六、知识来源

一、I/O调优的重要性

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

第一列为处理一个数据单元所需要的时间,第二列为对该数据单元进行磁盘读写所需要的时间,第三列为每秒能处理的数据单元数,第四列为改变第一列第二列的值所能产生的数据吞吐率的提升。 图中相对说明:单位处理时间减半,仅能提高吞吐率2.2%,I/O时间减半,吞吐几乎翻倍。操作系统移动的是大块数据(缓存区),而java.io类喜欢操作小块数据--单个字节、几行文本,有了NIO就可以轻松把大块数据备份到直接使用的地方(ByteBuffer对象)。

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

二、数据传输过程

1.磁盘到缓存区运动过程

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

数据从磁盘向运行中的进程的内存区域移动的过程 1.进程使用read()系统调用,要求其缓存区被填满 2.内核随机向磁盘控制硬件发出命令,要求从磁盘读取数据。 3.磁盘控制器把数据直接写入内核缓存区,这一步通过DMA完成,无需主CPU协助。 4.一旦磁盘控制器把缓存区装满,内核即把数据从内核空间额临时缓存区拷贝到进程执行read()调用时指定的缓存区。 用户空间:即常规线程所在区域,非特权区域,不能直接访问设备,JVM即常规线程,驻守于用户空间。 内核空间:是操作系统所在的区域,特权区域,能与设备控制器进行通信,控制者用户区域空间进程的运行状态等。所有的I/O都直接或者间接的通过内核空间。

进程一个系统调用,将一连串缓存区地址传递给操作系统,内核按顺序填充或者排干若干缓冲区,读的时候可以发散到多个用户缓存区,写的时候可以从多个用户缓存区把数据汇聚起来。 备注:内核试图对数据进行高速缓存或者预读取,所以进程所需要数据可能已经在内核空间里了,已在内核空间的只需要拷贝该数据即可。如果不在内核空间,则进程被挂起,内核将数据读到内存。

2.零字节拷贝

传统数据从文件传到套接字的路径

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

零字节拷贝方式

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

三、虚拟内存

1.虚拟内存好处

1.一个或者多个的虚拟地址可以指向同一个物理内存地址 2.虚拟内存空间可大于实际可用的硬件内存 下图用户空间和内核空间地址映射到同一个物理内存地址

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

2.内存页调度

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

进程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()内存分配时,只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,进而进入内核空间分配物理内存、更新进程缓存表,最后返回用户空间,恢复进程运行。如果没有这些假值,系统不会实际分配物理内存,防止在写入消息时发生缺页异常。 RoecketMQ存储--映射文件预热【源码笔记】

六、知识来源

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜农老梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档