索引节点 (Index Node)和 目录项(directory entry)
- 索引节点,简称 inode,用来记录文件的元数据,比如inode编号、文件大小、访问权限、修改日期、数据位置。
索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以记住索引节点同样占用磁盘空间。
- 目录项,简称 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。 不过不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。
索引节点和目录项记录了文件的元数据,以及文件见的目录关系,具体来说,文件数据到底是怎么存储的呢?是不是直接写到磁盘中就好了呢?
- 磁盘的读写 磁盘读写的最小单位是扇区,扇区 512B大小,如果每次都读写这么小的单位,效率很低。 文件系统把连续的扇区组成了逻辑块(四大基本要素),然后每次都以逻辑块为最小单元,来管理数据。 常见逻辑块大小 4KB,也就是 8个扇区组成。
磁盘格式化时,会被分成三个存储区域:1. 超级块(四大基本要素):存储整个文件系统的状态。
2.索引节点(四大基本要素)区 : 用来存储索引节点
3. 数据块(四大基本要素)区: 用来存储文件数据
虚拟文件系统
为了支持不同的文件系统,Linux 内核在用户进程和文件系统的中间,又引入一个抽象层,也就是虚拟文件系统VFS(Virtual File System)
VFS 定义了一组所有文件系统都支持的数据结构 和标准接口, 这样,用户进程和内核其他子系统,只需要跟VFS提供的统一接口进行交互就可以了,而不需要再关心底层的各种文件系统的实现细节。
文件系统
大致分为3类:
第一类:基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。常见的Ext4、XFS、OverlayFS等,都是这类文件系统。
第二类:基于内存的文件系统,也就是我们常说的虚拟文件系统。这类文件系统,不需要任何磁盘分配存储空间,但会占用内存。我们经常用到的 /proc 文件系统,其实就是一种常见的虚拟文件系统。此外, /sys 文件系统也属于这一类,主要向用户空间导出层次化的内核对象。
第三类: 网络文件系统,也就是用来访问其他计算机的文件系统,比如NFS、SMB、iSCSI 等。
这些文件系统,要先挂载到VFS目录树种的某个子目录(称为挂载点), 然后才能访问其中的文件。
文件系统I/O
把文件系统挂载到挂载点后,你就能通过挂载点,再去访问它管理的文件了。VFS提供了一组标准的文件访问接口。这些接口以系统调用的方式。
分类:
第一种,根据是否利用标准缓存库,可以把文件I/O 分为缓冲I/O 与 非缓冲I/O。
第二种,根据是否利用操作系统页缓存,分为 直接 I/O 和非直接 I/O。
第三种,根据应用程序是否阻塞自身运行,分为阻塞I/O 和 非阻塞 I/O
第四种,根据是否等待响应结果,分为同步和异步I/O.
Linux 一切皆文件,深刻含义。无论是普通文件和块设备、还是网络套接字和管道等,它们都是通过统一的VFS接口来访问的。
性能观测
容量
缓存
free 输出的Cache,是页缓存和可回收Slab缓存的和,可以从/proc/meminfo.直接获取
3057888 不等于 2998100 3057888-2998100 =59788(58M)
cat /proc/meminfo | grep -E "SReclaimable|Cached"
2930152+ 67948 = 2998100KB
可回收Slab缓存
= dentry + inode_cache + .....
目录项缓存 和 索引缓存
是通过 slab机制 /proc/meminfo 只给出了Slab 整体大小。
sudo cat /proc/slabinfo | grep -E "^#|dentry|inode"
dentry 目录项缓存 : 192
inode VFS索引节点缓存: 592
sudo cat /proc/slabinfo | awk '{sum+=$4 } END {print sum} '
91106.1 = 67948
slabtop 查看占用内存最多的缓存类型。