Linux 中一切皆文件
四大要素:

  • 目录项
  • 索引节点
  • 逻辑块
  • 超级块

    1、索引节点和目录项

  • 索引节点(inode):用来记录文件的元数据,比如node编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,会被持久化存储到磁盘中,会占用磁盘空间

  • 目录项(dentry):用来记录文件的名字、索引节点指针以及其他目录项的关联关系。多个关联的目录项,构成文件系统的目录结构。它是由内核维护的一个内存数据结构,也称目录项缓存

索引节点是每个文件的唯一标志,而目录项维护的是文件系统的树状结构。目录项和索引节点的关系是多对一。
实际上,磁盘读写的最小单位是 扇区,一个扇区只有 512 B大小。文件系统把连续的扇区组成了逻辑块。每次以逻辑块为最小单元,来管理数据。常见逻辑块大小 4 KB,也就是连续的8个扇区。
image.png
第一,目录项本身一个内存缓存,索引节点是存储到磁盘的。因此文件内存会缓存到页缓存 Cache中,索引节点也会缓存到内存中,便于访问
第二,磁盘在执行文件系统格式化的时候,会被分成三个存储区域

  • 超级块:存储整个文件系统的状态
  • 索引节点区:存储索引节点
  • 数据块区:存储文件数据

    2、虚拟文件系统

    为了支持不同的文件系统,linux 内核在用户进程和文件系统的中间,引入了抽象层,也就是 虚拟文件系统VFS(Virtual File System)。
    VFS定义了一组所有文件系统都支持的数据结构和标准接口。用户进程和内核中的其他子系统,只需要跟VFS提供的统一接口进行交互即可。
    image.png
    在VFS下方,linux支持各种文件系统,如 Ext4、XFS、NFS 等。按照存储位置不同,这些文件系统分为三类:

  • 基于磁盘的文件系统:数据直接存储在计算机本地挂载的磁盘中。如 Ext4、XFS、OverlayFS

  • 基于内存的文件系统:也就是 虚拟文件系统,如 /proc 文件系统、 /sys 文件系统。
  • 网络文件系统:用来访问其他计算机数据的文件系统,如 NFS、SMB、iSCSI

这些文件系统,要先挂载到 VFS 目录树中的某个子目录(挂载点),然后才能访问其中文件。如第一类,基于磁盘的文件系统,安装系统时,要先挂载一个跟目录(/),在根目录下再挂载其他文件系统(如 /proc、/sys、NFS)。

3、文件系统I/O

把文件系统挂载到挂载点后,就能通过挂载点,再去访问它管理的文件了。
cat命令为例,首先调用 open(),打开一个文件,然后调用 read(),读取文件内容,最后调用 write() ,把文件内容输出到控制台

  1. int open(const char *pathname, int flags, mode_t mode);
  2. ssize_t read(int fd, void *buf, size_t count);
  3. ssize_t write(int fd, const void *buf, size_t count);

1、是否利用标准库缓存

  • 缓冲 I/O:指利用标准库缓存来加速文件的访问,而标准库内存再通过系统调用
  • 非缓冲 I/O:指直接通过系统调用来访问文件,不再经过标准库缓存

2、是否利用操作系统的缓存页

  • 直接 I/O:指跳过操作系统的页缓存,直接跟文件系统交互来访问文件
  • 非直接 I/O:文件读写时,先经过系统的页缓存,然后有内核或额外的系统调用,真正写入磁盘

3、应用程序是否阻塞自身运行

  • 阻塞 I/O :指应用程序执行 I/O 操作后,如果没有获得响应,就会阻塞当前线程
  • 非阻塞 I/O :指应用程序执行 I/O 操作后,不会阻塞当前线程,可以继续执行其他任务,随后会通过轮询或者事件通知的形式,获取调用结果。

4、是否等待响应结果

  • 同步 I/O :指应用程序执行 I/O 操作后,要一直等到整个 I/O 完成后,才能获得 I/O 响应
  • 异步 I/O :指应用程序执行 I/O 操作后,不用等待完成和完成后的响应。等这次 I/O 完成后,响应会通过事件通知的方式,告诉应用程序

    4、工具

    1、df

    1. -h 按可读性更强展示
    2. -i 查看磁盘缓存

    image.png
    当发现索引节点空间不足,但磁盘空间充足时,很有可能是过多小文件导致的。

    2、缓存

    1、/proc/meminfo

    只能查看 Slab 的整体大小

    1. cat /proc/meminfo | grep -E "SReclaimable|Cached"

    image.png

    2、/proc/slabinfo

    内核使用 Slab 机制,管理目录项和索引节点的缓存。
    要查看具体的每一种 Slab 缓存

    1. cat /proc/slabinfo | grep -E '^#|dentry|inode'

    image.png

  • dentry行:表示目录项缓存

  • inode_cache 行:表示 VFS索引节点缓存

    3、slabtop

    1. # 按下c按照缓存大小排序,按下a按照活跃对象数排序
    2. slabtop
    image.png