Direct I/O 与正常高速缓存的 I/O

本文探讨了AIX操作系统中的Direct I/O概念及其与常规缓存I/O的区别。阐述了Direct I/O如何绕过内核缓存直接进行磁盘读写,以及这种方式的优势和潜在性能影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阅读AIX的手册,看到关于 Direct I/O 的一些描述:

直接 I/O 与正常高速缓存的 I/O

通常,JFS 或 JFS2 将文件页面高速缓存在内核存储器中。当应用程序执行文件读取请求时,如果文件页面不在内存中,则 JFS 或 JFS2 将数据从磁盘读取到文件高速缓存,然后将数据从文件高速缓存复制到用户缓冲区。对于应用程序的写操作,仅将数据从用户的缓冲区复制到高速缓存。以后执行对 磁盘的实际写入。

当高速缓存的使用率比较高时,这种高速缓存策略可以发挥完全的效用。它还启用从头读取、从后写入的策略。最后,它使文件写操作异步,允许应用程序继续处理,而不是等待 I/O 请求完成。

直接 I/O 是一种可选的高速缓存策略,它使得文件数据直接在磁盘和用户缓冲区之间传送。文件的直接 I/O 在功能上等同于设备的原始 I/O。应用程序可以在 JFS 或 JFS2 上使用直接 I/O。

直接 I/O 的优点

直接 I/O 的主要优点是,通过去除从高速缓存到用户缓冲区的复制环节,降低了文件读取和写入时 CPU 的使用率。这对具有非常低的高速缓存命中率文件数据而言,也是一种优点。如果高速缓存命中率低,则大部分读请求必须转至磁盘。直接 I/O 也可以有助于那些必须使用同步写操作的应用程序,因为这些写操作必须转至磁盘。在这两种情况下,因为取消了数据复制,所以 CPU 使用率降低。

直接 I/O 的另一个优点是它使得应用程序避免减弱其它文件高速缓存的效果。任何时候读取或写入文件时,该文件会争夺高速缓存中的空间。这种情况可能会使其它文件数据 被推出高速缓存。如果新高速缓存的数据具有非常差的重新使用特性,则高速缓存的效用可能会降低。直接 I/O 给予应用程序以识别正常的高速缓存策略无效的文件,因此为策略有效的文件释放了更多的空间。

直接 I/O 的性能损失

虽然直接 I/O 可以降低 CPU 使用率,但,使用它通常会造成需要较长的时间完成进程,尤其是对于相对较小的请求。这种损失是由于正常的速缓存 I/O 和直接 I/O 之间的基本差异造成的。

直接 I/O 读取

每次直接 I/O 读取都会造成磁盘的同步读;而正常高速缓存 I/O 策略的读取可以从高速缓存中得到满足,这二者是不同的。如果在正常高速缓存策略下数据有可能位于内存中,这可能会导致非常差的性能。

直接 I/O 还绕过正常 JFS 或 JFS2 从头读取算法。通过发出越来越大的读取请求,并使用应用程序进程重叠更多的块,这些算法可以对文件的顺序存取发挥完全的效用。

通过发出较大的读取请求,应用程序可以补偿 JFS 或 JFS2 从头读取的损失。最小限度,直接 I/O 阅读器应该发出至少 128k 的读取请求以匹配 JFS 或 JFS2 从头读取特性。

通过使用多线程或使用 aio_read 子例程发出异步直接 I/O 从头读取,应用程序还可以模拟 JFS 或 JFS2 从头读取。

直接 I/O 写

每次直接 I/O 写都会造成磁盘的同步写;而正常高速缓存 I/O 策略中数据仅被复制以后才写入到磁盘,这二者是不同的。这种基本差异可能会对转换为使用直接 I/O 的应用程序造成严重的性能损失。

冲突文件访问方式

为了避免使用直接 I/O 和使用正常高速缓存 I/O 的程序之间的一致性问题,直接 I/O 是一种排它的使用模式。如果打开多个文件,其中一些为直接打开而其它的不是直接打开,则文件会停留在正常高速缓存的访问方式。只有当文件直接 I/O 程序独占地打开时,文件才会被放置在直接 I/O 方式下。

同样,如果通过 shmat 或 mmap 系统调用,将文件映射到虚拟内存中,则文件将保持正常高速缓存方式。

任何时候取消(通过 close、munmap 或 shmdt 子例程)最后的冲突或非直接访问,JFS 或 JFS2 会试图将文件传送到直接 I/O 方式。将文件从正常方式更改为直接 I/O 方式可能相当费时,因为它需要将所有修改的页面写入到磁盘,并除去内存中所有的文件页面。

起码可以得到一个结论:DIO 有的时候会负面影响性能。这篇文档 Use Direct I/O to improve performance of your AIX applications

 

 

 

direct io是一种不用内核缓存的io,它可以做到直接将用户空间的内存直接写入磁盘或者将磁盘数据直接读到用户空间的缓冲区,这种策略就是不用内核的缓存而使用 用户自己设计的缓存,这一般在数据库系统中用到,初用linux的人在调用free命令的时候都会大吃一惊,为何文件cache占用了那么多的内存,太可 怕了啊,其实这正是表明了该用户是初用户,这正是linux的风格,空闲内存闲着也是闲着,既然没有用户用,那么就用来缓存文件数据,这样可以尽量加速 linux的用户感知速度,只要用户实际要用内存的时候,文件cahce肯定会让位,那么有人会问,即使文件cache会让位,那么将文件cahce换出 也需要时间,其实这个问题的解决很简单,就是维持系统空闲内存在一个范围内,这就是kswap的作用,可以做一个试验,就是在系统初启动的时候,执行cp -r /etc /home/zhaoya/test/,等待,看表,足足八秒,然后执行rm -rf /home/zhaoya/test/etc/,然后再执行cp -r /etc /home/zhaoya/test/,发现只用了3秒不到,这就是文件缓存的作用,可是不管怎么说有的用户还是对文件cache不看好,其实不想用文件 cache的人有两类,一类是觉得文件cache占用内存太多,另一类就是拥有自己的用户空间的cahce算法,不需要内核的cahce,这两种中,第一 种是错误的想法,第二种才是正确的想法。于是linux没有提供禁用文件cache的系统调用或者/proc接口,但是却给了对于单独文件禁用cahce 的方法,也就是说,如果说你想禁用cahce,那么如果你是觉得它占用内存太多,那么你就忍忍吧,好好再学学linux,系统不会让你禁用整个系统的文件 cache,如果你是觉得自己有用户空间的cahce,那么你一定是对于操作特殊的文件拥有自己的策略,于是在open系统调用中提供了O_DIRECT 标志,这标志表明这个文件打开后不再使用内核的cache,而是使用自己的cache,不过在某一个时间,如果你想失效系统中所有的文件cache,那么 可以将3写入/proc/sys/vm/drop_cahces文件,这个可以使用sysctl来进行。

还有一个问题就是带有 O_DIRECT标志打开的文件的mmap问题,通过读代码可以知道,mmap中没有判断有没有O_DIRECT标志的逻辑,并且在mmap中不管打开方 式如何,都会采用文件cache的方式,因为所谓文件的mmap就是将文件的内核cache页面直接映射到用户空间的虚拟地址空间,mmap的本意就是将 文件映射到用户空间,而linux中文件在内核内存中的唯一表示就是文件cache,于是mmap带有O_DIRECT标志的文件时,也会使用文件 cache,但是一旦直接read或者write这些直接读写的文件,那么就会在直接读写前将已经mmap到用户空间的该文件的内核cache页面设置为 脏,然后等待这些页面回写到磁盘后再开始直接io,因为不但这个文件可能同时被映射到用户空间,而且别的进程也可能打开该文件并且不带有O_DIRECT 标志,如此为了不出现数据不一致的错误,O_DIRECT打开的文件在读写的时候必须是独占该文件的。具体判断是否有别的进程映射该文件的方式就是搜索该 文件的mapping的优先搜索树,一旦这棵树不为空,那么就说明有进程映射这个文件,然后一个一个找到这些vma,并且根据反向映射将这些vma的页面 的进程的页表置为无效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值