缓存IO和直接IO
缓存IO和直接IO
缓存IO:数据从磁盘先通过DMA copy到内核空间,再从内核空间通过cpu copy到用户空间
直接IO:数据从磁盘通过DMA copy到用户空间
缓存IO
缓存IO又被称为标准IO,大多数文件系统的默认IO操作都是缓存IO
在Linux的缓存IO机制中吗,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间。
- 读操作
- 操作系统检查内核的缓冲区有没有需要的数据,如果已经缓存了,那么就直接从缓存中返回。否则从磁盘中读取,然后缓存在操作系统的缓存中。
- 写操作
- 将数据从用户空间复制到内核空间的缓存中。这时对用户程序来说写操作就已经完成,至于什么时候再写到磁盘中由操作系统决定。除非显示的调用的了sync同步命名
- 缓存IO的优点
- 在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全
- 可以减少读盘的次数,从而提高性能
- 缓存IO的缺点
- 在缓存IO机制中,DMA方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样,数据在传输过程中需要在应用程序地址空间(用户空间)和缓存(内核空间)直接进行多次数据拷贝操作,这个数据拷贝操作所带来的CPU已经内存开销是非常大的
直接IO
直接IO就是应用程序直接访问磁盘数据,而不经过内核缓冲区,也就是绕过内核缓冲区,自己管理IO缓存区,这样做的目的是减少一次内核缓冲区到用户程序缓存的数据复制
引入内核缓冲区的目的在于提高磁盘文件的访问性能,因为当进程需要读取磁盘文件时,如果文件内容已经在内核缓冲区中,那么就不需要再次访问磁盘。而当进程需要向文件写入数据是,实际上只是写到了内核缓冲区便告诉进程已经写成功,而真正写入磁盘是通过一定的策略进行延时的。
然而,对于一些较复杂的应用,比如数据库服务器,他们为了充分提高性能。希望绕过内核缓冲区,由自己在用户态空间时间并管理IO缓冲区,包括缓存机制和写延迟机制等,以支持独特的查询机制,比如数据库可以根据加合理的策略来提高查询缓存命中率。另一方面,绕过内核缓冲区也可以减少系统内存的开销,因为内核缓冲区本身就在使用系统内存。
直接IO的缺点就是如果直接访问的数据不再应用缓存中,那么每次数据都会直接从磁盘进行加载,这种直接加载会非常缓慢,通常直接IO跟异步IO结合使用会得到较好的性能
Linux提供了对这种需求的支持,即在open()系统调用中增加参数选项O_DIRECT,用它打开的文件便可以绕过内核缓冲区的直接访问,这样有效避免了CPU和内存的多余时间的开销。
顺便提一下,与O_DIRECT类似的一个选项是O_SYNC,后者只对写数据有效,它将写入内核缓冲区的数据立即写入磁盘,将机器故障时数据的丢失减少到最小,但是它仍然要经过内核缓冲区。