Linux IO中BIO和DIO

块存储是使用块设备为系统提供存储服务。块设备将信息存储在固定大小的块中,每个块都有自己的地址。

通常情况下,是通过文件系统来访问块设备,也可以直接使用裸设备,通过指定偏移和大小来读写裸设备。常见的块存储设备就是物理磁盘,在Linux系统下,还提供基于其他块设备之上的逻辑设备,如Device Mapper,软RAID等。

  1. IO栈

    Linux 4.10.0的IO栈如下图:
    1.png
    原图链接:
    https://www.thomas-krenn.com/en/wiki/Linux_Storage_Stack_Diagram#Diagram_for_Linux_Kernel_3.17

  2. 缓存 I/O (Buffered I/O)

    缓存I/O又被称作标准I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。有以下优点:
     缓存 I/O 使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理设备。
     缓存 I/O 可以减少读盘的次数,从而提高性能。
    在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,数据在传输过程中需要在应用程序地址空间和页缓存之间进行多次数据拷贝操作,带来的 CPU 以及内存开销是非常大的。
    对于某些特殊的应用程序来说,避开操作系统内核缓冲区而直接在应用程序地址空间和磁盘之间传输数据会比使用操作系统内核缓冲区获取更好的性能

  3. 直接I/O技术(Direct I/O)

    对于某些应用程序来说,它会有它自己的数据缓存机制,比如,它会将数据缓存在应用程序地址空间,这类应用程序完全不需要使用操作系统内核中的高速缓冲存储器,这类应用程序就被称作是自缓存应用程序( self-caching applications )。数据库管理系统是这类应用程序的一个代表。
    自缓存应用程序来说,缓存 I/O 明显不是一个好选择。可以使用直接 I/O(DIO) 技术。直接 I/O 技术非常适用于自缓存这类应用程序,该技术省略掉缓存 I/O 技术中操作系统内核缓冲区的使用,数据直接在应用程序地址空间和磁盘之间进行传输,从而使得自缓存应用程序可以省略掉复杂的系统级别的缓存结构,而执行程序自己定义的数据读写管理,从而降低系统级别的管理对应用程序访问数据的影响。

  4. 参考

    linux块设备IO栈浅析
    http://www.sysnote.org/2015/08/06/linux-io-stack/
    Linux 中直接 I/O 机制的介绍
    https://www.ibm.com/developerworks/cn/linux/l-cn-directio/
    Thomas-krenn—Linux I/O Stack
    https://www.thomas-krenn.com/en/wiki/Linux_Storage_Stack_Diagram#Diagram_for_Linux_Kernel_3.17
    一个IO的传奇一生
    http://alanwu.blog.51cto.com/3652632/1398744