在Ubuntu服务器运维中,磁盘性能是决定系统稳定性和应用响应速度的关键因素。直接使用fio(Flexible I/O Tester)工具进行基准测试,是获取真实、可重复性能数据的最有效方法。它能模拟各种负载,精确测量顺序读写、随机读写、IOPS和延迟等核心指标,帮你发现存储瓶颈,为硬件选型、文件系统调优或云盘配置提供坚实依据。

为什么fio是磁盘性能测试的首选工具?

与dd或hdparm等简单工具不同,fio提供了极其灵活和专业的测试框架。它能创建多线程或进程的并发负载,精确控制I/O引擎(如libaio)、块大小、读写比例、随机/顺序模式等参数。这意味着你可以模拟数据库的随机读写、视频流媒体的顺序大文件读写,或者混合负载场景,得到的数据直接反映生产环境中的性能表现。其跨平台特性和丰富的输出格式(文本、JSON、图形化),也使其成为运维和开发人员的标准工具。

在Ubuntu上安装fio

在绝大多数Ubuntu版本中,fio可以通过官方仓库直接安装。打开终端,执行以下命令即可:

sudo apt update
sudo apt install fio -y

安装完成后,可以通过 fio --version 确认安装成功。为了获得最准确的结果,建议测试时关闭其他不必要的应用程序,并在需要时使用sudo权限运行fio,以避免用户级I/O调度带来的影响。

理解fio的核心测试参数

编写fio测试任务的核心是理解其配置文件(job file)中的关键参数。一个典型的测试会定义全局段和多个任务段。主要参数包括:

filename: 指定测试的目标文件或设备,如 /dev/sdb/mnt/data/testfile。直接测试裸设备能排除文件系统缓存干扰。

direct: 设置为1时,使用直接I/O(O_DIRECT),绕过操作系统缓存,反映磁盘的真实吞吐量和延迟,这对数据库等应用至关重要。

ioengine: 选择I/O引擎,常用 libaio(Linux原生异步I/O),对于高性能测试至关重要。

rw: 定义读写模式,如 read(顺序读)、write(顺序写)、randread(随机读)、randwrite(随机写)、rw(顺序混合)、randrw(随机混合)。

bs: 块大小(block size),如4k、16k、1m。不同应用场景差异巨大,数据库OLTP常用4k或8k随机读写,而视频处理则用1m以上的顺序读写。

size: 每个线程读写的数据总量。测试总数据量应明显大于系统RAM,以避免缓存带来的虚高结果。

numjobs: 并发线程或进程数,用于模拟多用户/多连接压力。

runtime: 测试运行时间(秒),确保测试有足够时长以达到稳定状态。

group_reporting: 汇总所有job的统计信息,便于查看整体结果。

实战:执行四个关键基准测试

我们通过四个典型场景来全面评估磁盘性能。建议将下面的配置保存为独立的 .fio 文件,例如 seq_read.fio

1. 顺序读取(评估大文件连续读吞吐量)

[global]
ioengine=libaio
direct=1
time_based
runtime=60
group_reporting

[sequential-read]
bs=1M
rw=read
filename=/dev/sdb
numjobs=1
size=10G

运行命令:sudo fio seq_read.fio。重点关注输出中的 bw=(XXXX KiB/s)(带宽)和 iops(每秒I/O操作数)。对于顺序读写,带宽是核心指标。

2. 顺序写入(评估大文件连续写吞吐量)

[global]
ioengine=libaio
direct=1
time_based
runtime=60
group_reporting

[sequential-write]
bs=1M
rw=write
filename=/dev/sdb
numjobs=1
size=10G

注意:对非空白设备进行写测试会覆盖数据,请务必确认目标设备。

3. 随机读取(评估IOPS,关键于数据库和虚拟化)

[global]
ioengine=libaio
direct=1
time_based
runtime=60
group_reporting

[random-read]
bs=4k
rw=randread
filename=/dev/sdb
numjobs=4
iodepth=32
size=10G

这里引入了 iodepth(I/O队列深度),它控制同时发出的I/O请求数量,较高的队列深度能更好地压榨出NVMe SSD或高端企业级硬盘的潜力。此测试的 iops 值是核心。

4. 随机写入(评估写IOPS和写入延迟)

[global]
ioengine=libaio
direct=1
time_based
runtime=60
group_reporting

[random-write]
bs=4k
rw=randwrite
filename=/dev/sdb
numjobs=4
iodepth=32
size=10G

随机写入对SSD的寿命和性能是严峻考验,其IOPS和延迟(lat)是衡量存储设备响应能力的关键。

解读fio测试结果报告

fio的输出报告信息量很大,你需要抓住这几个关键行:

带宽(BW): 单位通常是 KiB/s 或 MiB/s。顺序测试中,这个值应接近磁盘的理论接口速度(扣除开销)。

IOPS: 每秒操作数。对于随机4K测试,普通SATA SSD可能在数万到十万级别,而NVMe SSD可达数十万甚至百万级。

延迟(lat): 包括平均延迟(lat avg)、最大延迟(lat max)和延迟百分比(如 clat percentiles 中的 99.00%、99.99%)。高百分位延迟(如P99.9)对保证应用流畅性至关重要,即使平均延迟很低,偶尔的超高延迟(延迟尖峰)也可能导致应用卡顿。

CPU利用率: 高IOPS测试时,观察用户态(usr)和系统态(sys)的CPU占用。如果CPU成为瓶颈,磁盘的真实性能可能未被完全发挥。

高级技巧与注意事项

混合负载测试: 使用 rw=randrw 并设置 rwmixread=70(读占70%),可以模拟更真实的数据库负载。

避免缓存影响: 确保 direct=1,并且测试数据量(size * numjobs)远大于可用内存。也可以在测试前执行 sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches 来清空缓存(注意生产环境慎用)。

测试目标选择: 要测试文件系统性能,就指定文件路径;要测试裸设备极限性能,则直接指定设备节点(如 /dev/nvme0n1p1)。测试文件时,可以预先使用 fallocate 创建文件,避免测试包含文件分配时间。

长期稳定性测试: 将 runtime 设置为数小时,并使用 --output=long_test.log 记录输出,可以观察性能是否随时间衰减(如SSD过热或SLC缓存用尽)。

从测试数据到运维决策

获取基准数据后,关键在于分析和应用:

横向对比: 将测试结果与厂商宣传的规格(特别是针对你的工作负载,如4K随机读IOPS)进行对比,验证是否符合预期。

瓶颈定位: 如果带宽或IOPS远低于预期,检查硬件接口(SATA III, PCIe 3.0 x4)、驱动程序、内核I/O调度器(cat /sys/block/sdX/queue/scheduler)或文件系统格式(XFS通常在大型顺序IO上优于ext4)。

配置调优依据: 数据库(如MySQL)的 innodb_buffer_pool_size 设置应参考顺序读写速度;innodb_io_capacity 的设置应参考随机写IOPS。云服务器选型时,不同规格的云硬盘性能差异巨大,fio测试数据是选择性价比最优方案的核心依据。

定期进行fio基准测试并建立性能档案,是高水平运维团队的标志。它不仅能让你在故障排查时心中有数,更能在系统扩容、迁移或升级时,做出数据驱动的、最可靠的决策。