Linux 文件 I/O 性能监控与分析指南
继 CPU 和网络之后,文件系统 I/O 是影响系统性能的第三大关键领域。无论是数据库响应缓慢、应用加载时间过长,还是日志写入延迟,其根源都可能指向磁盘 I/O 瓶颈。本章将深入探讨文件 I/O 的核心概念、监控指标,并详细拆解 iostat
、sysbench
等一系列核心命令,确保覆盖您提供的所有内容,助您成为 I/O 性能调优专家。
第一部分:文件 I/O 核心概念
在开始监控之前,我们必须理解衡量文件 I/O 性能的关键指标以及其背后的工作原理。
I/O 性能指标
- 读/写速度: 即吞吐量,衡量单位时间内成功传输的数据量。
- 读/写次数 (IOPS): 每秒的读写请求次数。
- I/O 等待时间: 进程因等待 I/O 操作而花费的时间,此值越大,说明文件操作越频繁或设备越慢。
I/O 的两种核心方式
1. 缓存 I/O (Cached I/O)
缓存 I/O,又称为标准 I/O,是大多数文件系统默认的工作模式。其工作流程是,数据先从磁盘复制到内核空间的缓冲区(页缓存),然后再从内核空间缓冲区复制到应用程序的地址空间。
- 读操作:操作系统会检查内核空间的页缓存中是否存在需要的数据。如果已缓存,则直接从缓存中返回数据;否则,系统会先从磁盘读取数据到内核缓冲区,然后再将数据从内核缓冲区复制到用户空间。
- 写操作:应用程序将数据从用户空间复制到内核空间的缓冲区。此时,对于用户程序而言,写操作就已经完成了。至于何时将数据从内核空间真正写回磁盘,则由操作系统决定,除非用户显式调用
sync
同步命令。
优点:
- 在一定程度上分离了内核空间和用户空间,保证了系统本身的运行安全。
- 通过缓存常用数据,可以显著减少实际的磁盘读取次数,从而提升性能。
缺点:
- 在缓存 I/O 机制中,数据无法直接在用户空间和磁盘之间传输。数据在传输过程中,需要在用户空间和内核空间(页缓存)之间进行多次数据拷贝,这会带来较大的 CPU 和内存开销。
2. 直接 I/O (Direct I/O)
直接 I/O 允许应用程序直接访问磁盘,从而绕过内核缓冲区,其主要目的是为了减少一次从内核缓冲区到用户进程地址空间的数据复制操作。像数据库管理系统(如 MySQL、Oracle)这类应用,它们更倾向于在用户空间实现自己的缓存机制,因此通常会选择使用直接 I/O。
第二部分:磁盘 I/O 性能监控与测试
iostat
命令详解
iostat
是一个强大的工具,用于报告 CPU 使用率 和 磁盘 I/O 统计信息。
1. 基本语法
iostat [选项] [间隔时间] [次数]
- 间隔时间:每次报告之间的时间间隔(秒)。
- 次数:报告输出的次数。若省略次数,则持续输出。
2. 常用选项
选项 | 说明 |
---|---|
-c | 仅显示 CPU 使用率统计 |
-d | 仅显示磁盘 I/O 统计 |
-x | 显示扩展的磁盘 I/O 统计(更详细) |
-k | 以 KB/s 为单位显示数据(默认) |
-m | 以 MB/s 为单位显示数据 |
-p DEVICE | 显示指定设备的统计(如 /dev/sda ) |
-t | 在输出中增加时间戳 |
-y | 跳过首次统计(避免显示系统启动以来的平均值) |
3. 输出字段解释
(1) CPU 统计 (iostat -c
)
字段 | 说明 |
---|---|
%user | 用户进程占用 CPU 百分比 |
%nice | 低优先级(nice )进程占用 CPU 百分比 |
%system | 内核进程占用 CPU 百分比 |
%iowait | CPU 等待 I/O 的时间百分比(高则可能磁盘瓶颈) |
%steal | 虚拟化环境下被其他虚拟机占用的 CPU 时间 |
%idle | CPU 空闲时间百分比 |
(2) 磁盘 I/O 统计 (iostat -d
或 iostat -dkx
)
基本磁盘统计 (iostat -d
)
字段 | 说明 |
---|---|
Device | 磁盘设备名(如 sda 、nvme0n1 ) |
tps | 每秒传输次数(I/O 请求数) |
kB_read/s | 每秒读取的数据量(KB/s) |
kB_wrtn/s | 每秒写入的数据量(KB/s) |
kB_dscd/s | 每秒丢弃的数据量(如 SSD 的 TRIM 操作) |
kB_read | 自系统启动以来读取的总数据量(KB) |
kB_wrtn | 自系统启动以来写入的总数据量(KB) |
扩展磁盘统计 (iostat -dx
)
字段 | 说明 |
---|---|
rrqm/s | 每秒合并的读请求数 |
wrqm/s | 每秒合并的写请求数 |
r/s | 每秒完成的读请求数 |
w/s | 每秒完成的写请求数 |
rkB/s | 每秒读取的数据量(KB/s) |
wkB/s | 每秒写入的数据量(KB/s) |
avgrq-sz | 平均每次 I/O 请求的数据大小(扇区数) |
avgqu-sz | 平均 I/O 队列长度 |
await | 平均每次 I/O 请求的等待时间(ms,包括队列+处理时间) |
r_await | 读请求的平均等待时间(ms) |
w_await | 写请求的平均等待时间(ms) |
svctm | 平均每次 I/O 请求的服务时间(ms,仅作参考) |
%util | 设备利用率(0%~100%,接近 100% 表示磁盘饱和) |
关于
await
和svctm
:await
可以理解为 I/O 请求的总响应时间,它包括了队列等待时间和实际的服务时间。如果await
的值远大于svctm
,说明 I/O 请求在队列中等待的时间很长,这通常意味着磁盘 I/O 存在性能问题。
4. 使用示例
# 同时监控 CPU 和磁盘,每秒输出一次,共 5 次
iostat 1 5
# 仅监控磁盘 I/O,每 2 秒输出一次
iostat -d 2
# 以 MB/s 为单位显示磁盘吞吐量
iostat -d -m 1
# 监控指定磁盘(如 /dev/nvme0n1)
iostat -p nvme0n1 1 3
# 带时间戳输出,便于记录
iostat -t 1 3
5. 常见问题分析
- 磁盘瓶颈
%util
接近 100%:磁盘 I/O 负载饱和。await
较高(例如 >10ms):磁盘响应慢,可能是硬件性能不足或请求堆积。avgqu-sz
> 1:I/O 请求正在排队,可能存在瓶颈。
- CPU 瓶颈 (I/O 相关)
%iowait
较高:CPU 大量时间在等待 I/O,根源是磁盘速度慢。
- 与其他工具结合:可以使用
iotop
按进程查看磁盘 I/O 使用情况,或使用vmstat
和sar
进行综合监控。 - 注意事项:
iostat
的首次输出是系统启动以来的平均值,后续才是实时数据。可以使用-y
选项跳过首次的平均值统计。
sysbench
性能测试工具
sysbench
是一个多功能的基准测试工具,可用于对 CPU、内存、磁盘和数据库进行压力测试。
1. CPU 测试
此测试用于评估 CPU 的计算能力。
# 计算 20000 以内的所有质数
sysbench cpu --cpu-max-prime=20000 run
- 关键指标:
events per second
(每秒事件数),越高越好。
2. 内存测试
此测试用于评估内存的读写速度。
sysbench memory --memory-block-size=1K --memory-total-size=10G run
- 关键指标:
MiB/s
(吞吐量)。
3. 磁盘 I/O 测试
这是一个三步过程:
步骤一:生成测试文件
sysbench fileio --file-total-size=1G prepare
步骤二:运行测试
# 运行随机读写测试
sysbench fileio --file-total-size=1G --file-test-mode=rndrw run
- 关键指标:
read/write throughput (MB/s)
(读/写吞吐量) 和IOPS
(每秒 I/O 操作数)。
步骤三:清理测试文件
sysbench fileio cleanup
一个更复杂的示例:
# 准备测试文件
sysbench --num-threads=4 --max-time=60 --test=fileio --file-num=10 --file-total-size=10G --file-test-mode=rndrw prepare
# 同时使用 iostat 进行监控
iostat -dkx 1 300
第三部分:磁盘空间与分区使用情况
swapon
:查看交换分区
Swap 分区通常被称为交换分区,它是一块特殊的硬盘空间。当系统物理内存不足时,操作系统会从内存中取出一部分暂时不用的数据放入交换分区,从而为当前运行的进程腾出内存空间。一般来说,swap 分区的容量建议是物理内存的 2 倍,但不超过 2GB。
swapon -s
df
:查看文件系统使用情况
该命令用于查看文件系统的硬盘挂载点和空间使用情况。
# 以人类可读的格式显示
df -h
# 同时显示文件系统类型
df -Th
du
:查看目录和文件大小
该命令用于统计目录或文件占用的磁盘空间大小。
-h
: 以人类可读的格式显示。-s
: 仅显示总计大小。-c
: 显示几个目录或文件的磁盘空间大小,并统计它们的总和。-a
: 显示目录下的所有文件和目录的大小。--max-depth=N
: 指定显示目录的层级深度。
示例:
# 显示当前所在目录的总大小
du -s
# 以人类可读格式显示 /home 目录的总大小
du -s -h /home
# 显示多个目录的大小并汇总
du -c /var/log /tmp
# 查看当前目录下一级子文件和子目录分别占用的磁盘容量
du -lh --max-depth=1