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