Linux 中一切皆文件
四大要素:
- 目录项
- 索引节点
- 逻辑块
-
1、索引节点和目录项
索引节点(inode):用来记录文件的元数据,比如node编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,会被持久化存储到磁盘中,会占用磁盘空间
- 目录项(dentry):用来记录文件的名字、索引节点指针以及其他目录项的关联关系。多个关联的目录项,构成文件系统的目录结构。它是由内核维护的一个内存数据结构,也称目录项缓存
索引节点是每个文件的唯一标志,而目录项维护的是文件系统的树状结构。目录项和索引节点的关系是多对一。
实际上,磁盘读写的最小单位是 扇区,一个扇区只有 512 B大小。文件系统把连续的扇区组成了逻辑块。每次以逻辑块为最小单元,来管理数据。常见逻辑块大小 4 KB,也就是连续的8个扇区。
第一,目录项本身一个内存缓存,索引节点是存储到磁盘的。因此文件内存会缓存到页缓存 Cache中,索引节点也会缓存到内存中,便于访问
第二,磁盘在执行文件系统格式化的时候,会被分成三个存储区域
- 超级块:存储整个文件系统的状态
- 索引节点区:存储索引节点
-
2、虚拟文件系统
为了支持不同的文件系统,linux 内核在用户进程和文件系统的中间,引入了抽象层,也就是 虚拟文件系统VFS(Virtual File System)。
VFS定义了一组所有文件系统都支持的数据结构和标准接口。用户进程和内核中的其他子系统,只需要跟VFS提供的统一接口进行交互即可。
在VFS下方,linux支持各种文件系统,如 Ext4、XFS、NFS 等。按照存储位置不同,这些文件系统分为三类: 基于磁盘的文件系统:数据直接存储在计算机本地挂载的磁盘中。如 Ext4、XFS、OverlayFS
- 基于内存的文件系统:也就是 虚拟文件系统,如 /proc 文件系统、 /sys 文件系统。
- 网络文件系统:用来访问其他计算机数据的文件系统,如 NFS、SMB、iSCSI
这些文件系统,要先挂载到 VFS 目录树中的某个子目录(挂载点),然后才能访问其中文件。如第一类,基于磁盘的文件系统,安装系统时,要先挂载一个跟目录(/),在根目录下再挂载其他文件系统(如 /proc、/sys、NFS)。
3、文件系统I/O
把文件系统挂载到挂载点后,就能通过挂载点,再去访问它管理的文件了。
以 cat命令为例,首先调用 open(),打开一个文件,然后调用 read(),读取文件内容,最后调用 write() ,把文件内容输出到控制台
int open(const char *pathname, int flags, mode_t mode);ssize_t read(int fd, void *buf, size_t count);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
-h 按可读性更强展示-i 查看磁盘缓存

当发现索引节点空间不足,但磁盘空间充足时,很有可能是过多小文件导致的。2、缓存
1、/proc/meminfo
只能查看 Slab 的整体大小
cat /proc/meminfo | grep -E "SReclaimable|Cached"
2、/proc/slabinfo
内核使用 Slab 机制,管理目录项和索引节点的缓存。
要查看具体的每一种 Slab 缓存cat /proc/slabinfo | grep -E '^#|dentry|inode'

dentry行:表示目录项缓存
- inode_cache 行:表示 VFS索引节点缓存
3、slabtop
# 按下c按照缓存大小排序,按下a按照活跃对象数排序slabtop

