Linux 文件系统观测工具(1)
Linux 文件系统性能问题通常不是单一指标能够解释的。一个磁盘“慢”,可能是磁盘本身 I/O 延迟高,也可能是 Page Cache 命中率低、内存不足、dirty page 太多、进程大量执行 fsync(),甚至只是文件系统挂载参数导致的行为不同。
因此,文件系统观测应该从几个层次展开:

1. mount:首先确认文件系统是什么
遇到文件系统问题,第一步往往不是看 I/O,而是确认:
这个目录到底挂载了什么文件系统?用了什么 mount option?
mount
典型输出:
/dev/nvme0n1p1 on /data type ext4 \
(rw,relatime,data=ordered)
这里最重要的信息包括:
●block device:/dev/nvme0n1p1
●mount point:/data
●filesystem type:ext4
●mount options:rw, relatime, data=ordered
例如:
mount | grep -E 'ext4|xfs|btrfs'
可以快速确认机器上有哪些主要文件系统。
为什么 mount 很重要?
不同文件系统的行为可能完全不同。
例如:
ext4
XFS
Btrfs
NFS
tmpfs
overlayfs
它们在:
●metadata
●journaling
●writeback
●page cache
●inode
●directory lookup
等方面都有不同实现。
所以看到:
I/O 很慢
之后,不能马上认为是 block device 的问题。
首先应该确认:
哪个 filesystem?
挂载在哪里?
使用了什么 mount option?
2. df:观察文件系统容量和 inode
虽然 df 不在传统的性能工具列表中,但对于文件系统观测非常重要。
df -h
例如:
FilesystemSizeUsed Avail Use% Mounted on
/dev/nvme0n1p1100G82G18G83% /data
这里主要观察:
●filesystem size
●used
●available
●utilization
更重要的是 inode:
df -i
例如:
FilesystemInodesIUsedIFree IUse% Mounted on
/dev/nvme0n1p16553600 6500000 5360099% /data
这时候可能出现:
磁盘还有空间
但是:
无法创建新文件
因为真正耗尽的是 inode。
所以:
df -h
回答:
空间够不够?
而:
df -i
回答:
inode 够不够?
这两个指标必须同时看。
3. free:观察 Page Cache 和可用内存
文件系统性能与内存关系非常密切,因为 Linux 会使用 Page Cache 缓存文件数据。
free -h
例如:
totalusedfreesharedbuff/cacheavailable
Mem:32G12G2G1G18G19G
对于文件系统问题,重点关注:
buff/cache
available
其中 buff/cache 很大并不一定是问题。
Linux 会主动利用空闲内存作为 cache:
Application
│
▼
PageCache
│
▼
Block Device
读取文件时:
read()
↓
Page Cache
↓
cache hit → 直接返回
如果没有命中:
read()
↓
Page Cache miss
↓
Disk I/O
↓
Page Cache
↓
Application
因此,文件系统性能问题不能简单地理解为:
free 内存少 = 内存不足。
更应该关注:
available
swap
page reclaim
dirty pages
I/O wait
4. top:从系统级问题找到具体进程
top 并不是专门的文件系统工具,但它非常适合回答:
到底哪个进程在制造文件系统压力?
重点关注:
%CPU
%MEM
TIME+
以及 CPU 总体状态:
us sy ni id wa hi si st
其中:
wa = I/O wait
例如:
%Cpu(s): 20.0 us, 10.0 sy, 0.0 ni, 55.0 id, 15.0 wa
wa 较高意味着 CPU 有较多时间在等待 I/O 完成。
但需要注意:
I/O wait 高并不等于某一个文件系统一定有问题。
它只能说明系统存在较明显的 I/O 等待。
进一步需要结合:
sar
vmstat
iostat
确定具体是哪类 I/O。
如果要定位进程,则可以:iotop
找到 CPU / I/O 相关的可疑进程,再进一步使用 strace。

5. vmstat:观察内存、回收和 I/O
vmstat 是观察 Linux 文件系统问题非常重要的工具。
vmstat 1
典型输出:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
rbswpdfreebuffcachesisobiboincs us sy id wa
2302G1G15G0050003000...... 20 10 50 20
对于文件系统问题,重点看:
bi
表示从 block device 读入的数据。
持续升高可能意味着:
Page Cache miss
↓
大量 filesystem read
↓
Block I/O

bo
表示写出到 block device 的数据。
例如:
Application
↓
write()
↓
Page Cache
↓
Dirty Pages
↓
Writeback
↓
Block Device
因此大量 bo 往往意味着系统正在进行较明显的 writeback。

si / so
分别是:
si = swap in
so = swap out
如果出现:
so 很高
说明内存压力可能已经导致 swap。
这时文件系统 I/O 性能可能进一步恶化,因为系统同时存在:
Filesystem I/O
+
Swap I/O

6. sar:持续观察文件系统 I/O
如果说:
vmstat
适合快速观察系统状态,那么:
sar
更加适合做历史统计和持续监控。
例如:
sar -b 1
可以观察 block I/O:
tps
rtps
wtps
bread/s
bwrtn/s
这些指标可以帮助回答:
系统到底产生了多少 block I/O?
例如:
tps
表示每秒 I/O 请求数。
而:
bread/s
bwrtn/s
分别表示每秒读取和写入的数据量。
这可以帮助区分:
大量小 I/O
和:
少量大 I/O
例如:
tps = 50000
bread/s = 100 MB/s
说明可能存在大量小 I/O。
而:
tps = 100
bread/s = 1 GB/s
则更像大量 sequential / large I/O。
说明: sar 看到的block io,严格来说block io 不完全等于文件系统io, 可能会被放大,缩小。有时候只是间接观察,非常不准确。应该以iotop, filetop为准
7. slabtop:观察内核 filesystem cache
Linux 文件系统不仅缓存文件数据,还需要缓存大量 metadata。
例如:
inode
dentry
file
buffer
filesystem-specific objects
这些对象大量存在于 kernel slab allocator 中。
可以使用:
slabtop
例如:
OBJSACTIVEUSE OBJ SIZESLABS OBJ/SLAB CACHE SIZE NAME
...
100K95K95%0.58K.........inode_cache
200K190K95%0.19K.........dentry
对于文件系统问题,重点关注:
dentry
inode
dentry cache
dentry 用于缓存 directory entry
dentry cache 可以减少重复的目录查找。

inode cache
inode 保存文件的 metadata
大量小文件操作可能导致:
inode cache
dentry cache
占用大量内核内存。
因此,当系统存在:
大量小文件
+
频繁 create/unlink/stat/open
slabtop 非常有价值。

8. strace:从 I/O 下降到 filesystem syscall
前面的工具大多回答:
系统发生了什么?
而 strace 可以进一步回答:
哪个系统调用导致了这个行为?
例如:
strace -p
观察:
openat()
read()
write()
fsync()
fdatasync()
stat()
fstat()
rename()
unlink()
read/write
例如:
read(3, ..., 4096) = 4096
write(4, ..., 4096) = 4096
说明进程正在进行文件读写。
但需要注意:
read() 返回成功,并不代表每次都访问物理磁盘。
因为数据可能已经在 Page Cache 中。

fsync
特别值得关注:
fsync(fd)
fdatasync(fd)
例如:
write()
fsync()
write()
fsync()
write()
fsync()
这种模式可能产生大量同步 I/O。
应用程序本身可能没有很高的吞吐量,但由于频繁要求:
write → flush → wait
导致 I/O latency 很高。
stat / openat
如果应用程序频繁执行:
stat()
openat()
close()
而不是大量 read() / write(),问题可能不是 data I/O,而是:
metadata workload
典型场景:
大量小文件
大量目录扫描
编译系统
这时候:
dentry
inode
directory lookup
可能比真正的数据读写更加重要。

9. 建立一套文件系统观测思维
可以把这些工具按照观察层次整理成:
LinuxFilesystem
│
┌─────────────┼────────┐
│││
CapacityMemoryI/O
│││
df/ mountfree / vmstatsar / vmstat
│
▼
Process
│
top
│
▼
Syscalllevel
│
strace
│
▼
Kernelcache
│
slabtop
实际排查时,可以遵循:
第一步:确认文件系统
mount
df -h
df -i
回答:
是什么 filesystem?
挂在哪里?
空间够吗?
inode 够吗?
第二步:确认系统是否存在 I/O 压力
vmstat 1
sar -b 1
回答:
是否存在大量 block I/O?
read 多还是 write 多?
是否存在 swap?
是否存在大量 blocked task?
第三步:寻找进程
iotop
回答:
谁可能制造了这些 I/O?
第四步:观察 filesystem metadata cache
slabtop
回答:
dentry/inode 是否异常?
是否存在大量 metadata workload?
第五步:进入系统调用层
strace -p
回答:
到底是 read/write?
还是 fsync?
还是 open/stat/unlink?
最终形成一条完整的定位路径:
Filesystem
↓
Capacity
↓
Memory(page-cache)
↓
Block I/O
↓
Process
↓
Syscall
↓
Filesystem metadata / cache
10. 一个简单的文件系统排障 Checklist
当你发现“磁盘性能很差”时,可以快速执行:
# 1. filesystem / mount
mount
df -h
df -i
# 2. memory / cache
free -h
# 3. system I/O
vmstat 1
sar -b 1
# 4. process
top
# 5. kernel filesystem cache
slabtop
# 6. syscall
strace -p
但要注意一个重要问题:
这套工具可以很好地观察 filesystem 层,但不能完整替代 block-device I/O 工具。
如果 vmstat / sar 已经发现明显 I/O,下一步通常应该加入:
iostat -xz 1
进一步观察:
%util
await
r_await
w_await
r/s
w/s
rkB/s
wkB/s
queue depth
这样才能把:
Filesystem
↓
Page Cache
↓
Writeback
↓
Block Layer
↓
NVMe / SSD / HDD
这一整条路径串起来。
因此,Linux 文件系统性能观测的核心并不是记住一堆命令,而是建立“指标 → 层次 → 定位”的思维方式。