一.知识回顾
【0.IO在开发中有着举足轻重的地位,所以我们非常有必要学习。IO性能基石专栏都整理好了,可根据需要进行学习!】
【1.性能基石之IO~~~Linux操作系统相关知识体系补充&虚拟文件系统&文件描述符&PageCache内核缓存页】
二.Page Cache 缓存页
【性能基石之IO~~~Linux操作系统相关知识体系补充&虚拟文件系统&文件描述符&PageCache内核缓存页】
下面这张图来自于网络,可以帮助我们大致理解整个文件系统中PageCache所处的关键作用:

三.直接IO、缓存IO、内存映射mmap
3.1 直接IO Direct IO
- 直接IO就是应用程序直接访问磁盘数据,而不经过内核缓冲区,也就是绕过内核缓冲区,需要自己管理IO缓存区,这样做的目的是减少一次内核缓冲区到用户程序缓存的数据复制(减少开销)。
- 引入内核缓冲区的目的在于提高磁盘文件的访问性能,因为当进程需要读取磁盘文件时,如果文件内容已经在内核缓冲区中,那么就不需要再次访问磁盘。而当进程需要向文件写入数据时,实际上只是写到了内核缓冲区便告诉进程已经写成功,而真正写入磁盘是通过一定的策略进行延时的。
拓展: 对于一些较复杂的应用,比如数据库服务器,他们为了充分提高性能。希望绕过内核缓冲区,由自己在用户态空间时间并管理IO缓冲区,包括缓存机制和写延迟机制等,以支持独特的查询机制,比如数据库可以根据加合理的策略来提高查询缓存命中率。另一方面,绕过内核缓冲区也可以减少系统内存的开销,因为内核缓冲区本身就在使用系统内存。
- 直接IO的缺点:如果访问的数据不在应用程序缓存中,那么每次数据都会直接从磁盘加载,这种直接加载会非常缓慢。通常直接IO与异步IO结合使用,会得到比较好的性能。(异步IO:当访问数据的线程发出请求之后,线程会接着去处理其他事,而不是阻塞等待)。

3.2 缓存IO Buffered IO
- 缓存I/O又被称作标准I/O,大多数文件系统的默认I/O操作都是缓存I/O。在Linux的缓存I/O机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间。
- 缓存I/O的优点:首先,在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全;其次,可以减少读盘的次数,从而提高性能。
- 缓存I/O的缺点:在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样,数据在传输过程中需要在应用程序地址空间(用户空间)和缓存(内核空间)之间进行多次数据拷贝操作,这些数据拷贝操作所带来的CPU以及内存开销是非常大的。

3.3 Memory-Mapped IO mmap
- 内存映射是指将硬盘上文件的位置与进程逻辑地址空间中一块大小相同的区域一一对应,当要访问内存中一段数据时,转换为访问文件的某一段数据。这种方式的目的同样是减少数据在用户空间和内核空间之间的拷贝操作。当大量数据需要传输的时候,采用内存映射方式去访问文件会获得比较好的效率。
- 使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。
- 简而言之mmap用于把文件映射到内存空间中,简单说mmap就是把一个文件的内容在内存里面做一个映像。映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。那么对于内核空间<---->用户空间两者之间需要大量数据传输等操作的话效率是非常高的。

四.Buffer IO在堆内,堆外IO详细过程与mmap映射过程?
下面这张图来自于马士兵教育周老师,

五.文件一致性问题&Dirty概念&解决方案
5.1文件一致性问题?
Page Cache 是对磁盘上 page(页)的内存缓存,同时可以用于读/写操作。一切内存缓存都存在一致性问题:内存中的数据与磁盘中的数据不一致。
5.2 Dirty相关概念?
如果发生写操作并且对应的数据在 Page Cache 中,那么写操作就会直接作用于 Page Cache 中,此时如果数据还没刷新到磁盘,那么内存中的数据就领先于磁盘,此时对应 page 就被称为 Dirty page。
5.3 Linux中实现文件一致性的俩种方式&对应的三种系统调用
5.3.1 Linux中实现文件一致性的俩种方式
Write Through(写穿):向用户层提供特定接口,应用程序可主动调用接口来保证文件一致性;
Write back(写回):系统中存在定期任务(表现形式为内核线程),周期性地同步文件系统中文件脏数据块,这是默认的 Linux 一致性方案;
5.3.2 三种系统调用
上述两种方式最终都依赖于系统调用,主要分为如下三种系统调用:
| 方法 | 含义 |
|---|---|
| fsync(int fd) | 将fd代表的文件的脏数据和脏元数据全部刷新至磁盘中 |
| fdatasync(int fd) | 将fd代表的文件的脏数据刷新至磁盘,同时对必要的元数据刷新至磁盘中 |
| sync() | 将系统中所有的脏文件数据和脏元数据全部刷新到磁盘中 |
好了,到这里【性能基石之IO~~~Page Cache缓存页&直接IO、缓存IO、内存映射mmap&文件一致性问题&Dirty概念&解决方案&Buffer IO在堆内,堆外IO详细过程与mmap映射过程】就结束了,更多内容,不断学习,不断积累,不断创作中。
本文围绕Linux的IO相关知识展开。介绍了Page Cache缓存页,阐述直接IO、缓存IO、内存映射mmap三种IO方式的原理、优缺点。还探讨了文件一致性问题,解释了Dirty相关概念,并给出Linux实现文件一致性的两种方式及对应的三种系统调用。
1810

被折叠的 条评论
为什么被折叠?



