IO 技术栈

发布于 2025-02-16 21:54:30 字数 3564 浏览 11 评论 0

提供了软件与其它数据存储介质交换数据的能力

Linux 系统 I/O 栈主要包括磁盘和文件系统:

1. 磁盘:为系统数据提供持久化存储,在 linux 系统中磁盘是作为一个块设备来管理的,以块为单位读写数据,通常包括本地磁盘设备和网络存储

2. 文件系统:提供管理系统文件的树状结构,在 linux 系统中,一切皆文件,普通的文件、目录、块设备、套接字以及管道都是通过统一的文件系统管理,文件系统为每个文件都分配一个索引节点及一个目录项数据结构,用来记录文件的元信息及目录结构:

  1. 索引节点:inode 用来记录文件的大小,修改日期,访问权限、数据位置等元信息,inode 跟文件一一对应,inode 信息也要持久化存储到磁盘
  2. 目录项结构:dentry 用来记录文件的名字、索引节点指针以及与其他目录项的关联关系,目录项存储在内存中

换句话说,索引节点是每个文件的唯一标志,而目录项维护的正是文件系统的树状结构。目录项和索引节点的关系是多对一,你可以简单理解为,一个文件可以有多个别名。

举个例子,通过硬链接为文件创建的别名,就会对应不同的目录项,不过这些目录项本质上还是链接同一个文件,所以,它们的索引节点相同。

索引节点和目录项纪录了文件的元数据,以及文件间的目录关系,那么具体来说,文件数据到底是怎么存储的呢?是不是直接写到磁盘中就好了呢?

实际上,磁盘读写的最小单位是扇区,然而扇区只有 512B 大小,如果每次都读写这么小的单位,效率一定很低。所以,文件系统又把连续的扇区组成了逻辑块,然后每次都以逻辑块为最小单元,来管理数据。常见的逻辑块大小为 4KB,也就是由连续的 8 个扇区组成。

img

第一,目录项本身就是一个内存缓存,而索引节点则是存储在磁盘中的数据。在前面的 Buffer 和 Cache 原理中,我曾经提到过,为了协调慢速磁盘与快速 CPU 的性能差异,文件内容会缓存到页缓存 Cache 中。

那么,这些索引节点自然也会缓存到内存中,加速文件的访问。

第二,磁盘在执行文件系统格式化时,会被分成三个存储区域,超级块、索引节点区和数据块区。其中,

  • 超级块,存储整个文件系统的状态。
  • 索引节点区,用来存储索引节点。
  • 数据块区,则用来存储文件数据。

文件系统,本身是对存储设备上的文件,进行组织管理的机制。组织方式不同,就会形成不同的文件系统。

换句话说,索引节点是每个文件的唯一标志,而目录项维护的正是文件系统的树状结构。目录项和索引节点的关系是多对一,你可以简单理解为,一个文件可以有多个别名。

举个例子,通过硬链接为文件创建的别名,就会对应不同的目录项,不过这些目录项本质上还是链接同一个文件,所以,它们的索引节点相同。

虚拟文件系统级缓存

虚拟文件系统:VFS 给不同类型的文件系统提供了通用的接口,用户程序和内核其他子系统不需要了解各种文件系统的实现细节,通过 VFS 提供的接口就可以实现对文件系统的调用,VFS 是处于系统调用和文件系统中间的一个抽象层,EXT3、EXT4、NFS 等文件系统需要挂载到 VFS 目录树中的某个子目录下面才能被使用,比如 LINUX 系统的根目录/

这些文件系统可以分为三类。

  • 第一类是基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。常见的 Ext4、XFS、OverlayFS 等,都是这类文件系统。
  • 第二类是基于内存的文件系统,也就是我们常说的虚拟文件系统。这类文件系统,不需要任何磁盘分配存储空间,但会占用内存。我们经常用到的 /proc 文件系统,其实就是一种最常见的虚拟文件系统。此外,/sys 文件系统也属于这一类,主要向用户空间导出层次化的内核对象。
  • 第三类是网络文件系统,也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等。

这些文件系统,要先挂载到 VFS 目录树中的某个子目录(称为挂载点),然后才能访问其中的文件。拿第一类,也就是基于磁盘的文件系统为例,在安装系统时,要先挂载一个根目录(/),在根目录下再把其他文件系统(比如其他的磁盘分区、/proc 文件系统、/sys 文件系统、NFS 等)挂载进来。

缓存:为了协调快速 CPU 及慢速磁盘之间的性能差异,LINUX 文件系统通过各种缓存实现文件的快速访问,主要包括:

  1. 页缓存:缓存了虚拟内存页面,其中包括了文件系统的页面,提升了文件和目录的性能,当系统系统内存不足时,页缓存是可以回收的,可通过如下命令: grep "Cached" /proc/meminfo ​ 查看系统页缓存大小
  2. 目录项缓存:dentry 记录了从目录项到 VFS inode 的映射关系,提高了路径名查找的性能, 可通过如下命令: grep "dentry" /proc/slabinfo ​ 查看系统目录项缓存大小
  3. 索引节点缓存: inode_cache 缓存的对象是 inode,包括文件访问权限、更新时间戳、文件大小等信息,可通过如下命令:grep "inode_cache" /proc/slabinfo 查看索引节点缓存大小

文件缓存是这么计算的

/proc/meminfo 中

11  Active(file):     728232 kB
12  Inactive(file):   400104 kB

这两个值得总和

磁盘 IO

在 linux 系统中磁盘是作为一个块设备来管理的,以块为单位读写数据,为了减少不同的块设备差异带来的影响,类似虚拟文件系统 VFS,linux 通过一个统一的通用块层来管理各种块设备,主要功能如下:

  1. 为文件系统和应用程序,提供访问块设备的标准接口,将各种磁盘设备抽象为统一的块设备来管理
  2. 对 I/O 请求进行调度,通过重新排序,请求合并等措施优化磁盘读写效率

I/O 调度器对 I/O 请求进行排序,具体由采用的调度策略决定,主要策略如下

  • None:不做任何调度,常用于虚拟机,磁盘 I/O 调度取决了宿主物理机策略
  • Noop:一个先入先出的队列,只做一些基本的请求合并,适用于 SSD 磁盘
  • Deadline:为每个 I/O 请求延时设定截止时间,将要达到截止时间的请求被优先处理,共使用三个队列:读 FIFO、写 FIFO 和排序队列,通常适用于 I/O 求情大量的业务,比如数据库
  • Cfq:完全公平队列调度把 I/O 时间片分配给进程,确保磁盘资源的公平使用,通常作为默认选项,可通过 ionice 命令对用户进程设定优先级和类别

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

上一篇:

下一篇:

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

野の

暂无简介

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文