Linux文件系统是怎么工作的?( 三 )


容量对文件系统来说,最常见的一个问题就是空间不足 。当然,你可能本身就知道,用 df 命令,就能查看文件系统的磁盘空间使用情况 。比如:
$ df /dev/sda1Filesystem1K-blocksUsed Available Use% Mounted on/dev/sda130308240 31670202712483611% /你可以看到,我的根文件系统只使用了 11% 的空间 。这里还要注意,总空间用 1K-blocks的数量来表示,你可以给 df 加上 -h 选项,以获得更好的可读性:
$ df -h /dev/sda1FilesystemSizeUsed Avail Use% Mounted on/dev/sda129G3.1G26G11% /不过有时候,明明你碰到了空间不足的问题,可是用 df 查看磁盘空间后,却发现剩余空间还有很多 。这是怎么回事呢?
不知道你还记不记得,刚才我强调的一个细节 。除了文件数据,索引节点也占用磁盘空间 。你可以给 df 命令加上 -i 参数,查看索引节点的使用情况,如下所示:
$ df -i /dev/sda1FilesystemInodesIUsedIFree IUse% Mounted on/dev/sda13870720 157460 37132605% /索引节点的容量,(也就是 Inode 个数)是在格式化磁盘时设定好的,一般由格式化工具自动生成 。当你发现索引节点空间不足,但磁盘空间充足时,很可能就是过多小文件导致的 。
所以,一般来说,删除这些小文件,或者把它们移动到索引节点充足的其他磁盘中,就可以解决这个问题 。
缓存在前面 Cache 案例中,我已经介绍过,可以用 free 或 vmstat,来观察页缓存的大小 。复习一下,free 输出的 Cache,是页缓存和可回收 Slab 缓存的和,你可以从/proc/meminfo ,直接得到它们的大小:
$ cat /proc/meminfo | grep -E "SReclaimable|Cached"Cached:748316 kBSwapCached:0 kBSReclaimable:179508 kB话说回来,文件系统中的目录项和索引节点缓存,又该如何观察呢?
实际上,内核使用 Slab 机制,管理目录项和索引节点的缓存 。/proc/meminfo 只给出了Slab 的整体大小,具体到每一种 Slab 缓存,还要查看 /proc/slabinfo 这个文件 。
比如,运行下面的命令,你就可以得到,所有目录项和各种文件系统索引节点的缓存情况:
$ cat /proc/slabinfo | grep -E '^#|dentry|inode'# name<active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunabxfs_inode00960174 : tunables000 : slabdata...ext4_inode_cache32104345901088154 : tunables000 : slabdatasock_inode_cache11901242704234 : tunables000 : slabdatashmem_inode_cache16222139712234 : tunables000 : slabdataproc_inode_cache35604080680122 : tunables000 : slabdatainode_cache2517225818608132 : tunables000 : slabdatadentry76050 121296192211 : tunables000 : slabdata这个界面中,dentry 行表示目录项缓存,inode_cache 行,表示 VFS 索引节点缓存,其余的则是各种文件系统的索引节点缓存 。
/proc/slabinfo 的列比较多,具体含义你可以查询man slabinfo 。在实际性能分析中,我们更常使用 slabtop,来找到占用内存最多的缓存类型 。
比如,下面就是我运行 slabtop 得到的结果:
#按下c按照缓存大小排序,按下a按照活跃对象数排序$ slabtopActive / Total Objects (% used): 277970 / 358914 (77.4%)Active / Total Slabs (% used): 12414 / 12414 (100.0%)Active / Total Caches (% used): 83 / 135 (61.5%)Active / Total Size (% used): 57816.88K / 73307.70K (78.9%)Minimum / Average / Maximum Object : 0.01K / 0.20K / 22.88KOBJS ACTIVEUSE OBJ SIZESLABS OBJ/SLAB CACHE SIZE NAME69804230940%0.19K33242113296K dentry16380158540%0.59K12601310080K inode_cache58260553970%0.13K1942307768K kernfs_node_cache4854130%5.69K9753104K task_struct147213970%2.00K92162944K kmalloc-2048从这个结果你可以看到,在我的系统中,目录项和索引节点占用了最多的 Slab 缓存 。不过它们占用的内存其实并不大,加起来也只有 23MB 左右 。
总结本文,我带你梳理了 Linux 文件系统的工作原理 。
文件系统,是对存储设备上的文件,进行组织管理的一种机制 。为了支持各类不同的文件系统,Linux 在各种文件系统实现上,抽象了一层虚拟文件系统(VFS) 。
VFS 定义了一组所有文件系统都支持的数据结构和标准接口 。这样,用户进程和内核中的其他子系统,就只需要跟 VFS 提供的统一接口进行交互 。
为了降低慢速磁盘对性能的影响,文件系统又通过页缓存、目录项缓存以及索引节点缓存,缓和磁盘延迟对应用程序的影响 。
在性能观测方面,本文主要讲了容量和缓存的指标 。下一节,我们将会学习 Linux 磁盘 I/O的工作原理,并掌握磁盘 I/O 的性能观测方法 。

【Linux文件系统是怎么工作的?】


推荐阅读