fio(Flexible I/O Tester)是一个用于基准测试和压力测试磁盘和文件系统的工具。它支持多种I/O引擎(同步/异步、直接I/O、内存映射等)、多种I/O类型(顺序/随机读写)和详细的统计报告。广泛用于评估存储设备的性能、验证硬件规格和系统调优。
# Ubuntu/Debian
sudo apt-get install fio
# RHEL/CentOS 7
sudo yum install fio
# RHEL/CentOS 8/Fedora
sudo dnf install fio
# Arch Linux
sudo pacman -S fio
# 从源码编译安装
git clone https://github.com/axboe/fio
cd fio
./configure
make
sudo make install
# 验证安装
fio --version
# 命令行直接测试
fio [选项] [任务文件]
# 使用任务文件(推荐)
fio jobfile.fio
libaio: Linux原生异步I/Osync: 基本同步I/Opsync: 预读同步I/Oposixaio: POSIX异步I/Ommap: 内存映射文件splice: Linux splice I/Onull: 空操作(仅用于测试框架)read: 顺序读write: 顺序写randread: 随机读randwrite: 随机写rw: 混合读写randrw: 随机混合读写trim: TRIM/丢弃操作| 参数 | 说明 | 示例 |
|---|---|---|
--name= |
测试任务名称 | --name=test_job |
--filename= |
测试文件路径 | --filename=/dev/sdb 或 --filename=testfile |
--size= |
测试文件大小 | --size=1G, --size=100%(使用全部空间) |
--rw= |
I/O操作类型 | --rw=read, --rw=randwrite, --rw=randrw |
--bs= |
块大小(block size) | --bs=4k, --bs=1M, --bs=4k,8k(混合) |
--ioengine= |
I/O引擎类型 | --ioengine=libaio, --ioengine=sync |
--iodepth= |
I/O队列深度 | --iodepth=32(常用于异步I/O) |
--numjobs= |
并发任务数 | --numjobs=4(模拟4个并发客户端) |
--runtime= |
运行时间(秒) | --runtime=60(运行60秒) |
--time_based |
基于时间而非大小运行 | --time_based |
--direct= |
是否使用直接I/O(绕过缓存) | --direct=1(启用) |
--group_reporting |
分组报告统计信息 | --group_reporting |
--output= |
输出结果文件 | --output=result.json |
--output-format= |
输出格式 | --output-format=json,normal |
# 测试顺序读性能(1M块大小,运行60秒)
fio --name=seq_read --filename=/dev/sdb --rw=read --bs=1M \
--size=10G --runtime=60 --ioengine=libaio --direct=1 \
--group_reporting
# 测试顺序写性能
fio --name=seq_write --filename=/dev/sdb --rw=write --bs=1M \
--size=10G --runtime=60 --ioengine=libaio --direct=1 \
--group_reporting
# 4K随机读测试
fio --name=4k_randread --filename=/dev/sdb --rw=randread --bs=4k \
--size=10G --runtime=60 --ioengine=libaio --iodepth=32 \
--direct=1 --group_reporting
# 4K随机写测试
fio --name=4k_randwrite --filename=/dev/sdb --rw=randwrite --bs=4k \
--size=10G --runtime=60 --ioengine=libaio --iodepth=32 \
--direct=1 --group_reporting
# 70%读,30%写的混合测试
fio --name=mixed_rw --filename=/dev/sdb --rw=randrw --rwmixread=70 \
--rwmixwrite=30 --bs=4k --size=10G --runtime=60 \
--ioengine=libaio --iodepth=32 --direct=1 --group_reporting
创建测试配置文件 test.fio:
# test.fio - 顺序读写测试
[global]
ioengine=libaio
iodepth=16
size=1G
direct=1
runtime=30
time_based
[seq-read]
name=sequential-read-test
filename=/dev/sdb
rw=read
bs=1M
[seq-write]
name=sequential-write-test
filename=/dev/sdb
rw=write
bs=1M
[rand-read]
name=random-read-test
filename=/dev/sdb
rw=randread
bs=4k
[rand-write]
name=random-write-test
filename=/dev/sdb
rw=randwrite
bs=4k
运行任务文件:
fio test.fio
# 4个并发任务进行随机读测试
fio --name=concurrent_test --filename=/dev/sdb --rw=randread \
--bs=4k --size=10G --runtime=60 --ioengine=libaio \
--iodepth=32 --numjobs=4 --direct=1 --group_reporting
# 每个任务使用不同的文件
fio --name=multi_file --filename=/dev/sdb:/dev/sdc:/dev/sdd \
--rw=randread --bs=4k --size=10G --runtime=60 \
--ioengine=libaio --iodepth=32 --numjobs=3 --direct=1
# 模拟OLTP数据库负载(8K随机读写,75%读,25%写)
fio --name=oltp_sim --filename=/dev/sdb --rw=randrw \
--rwmixread=75 --rwmixwrite=25 --bs=8k --size=20G \
--runtime=120 --ioengine=libaio --iodepth=128 \
--numjobs=8 --direct=1 --group_reporting
# 生成JSON格式的测试报告
fio --name=test --filename=/dev/sdb --rw=randread --bs=4k \
--size=1G --runtime=30 --ioengine=libaio --direct=1 \
--output=result.json --output-format=json
# 同时生成普通和JSON格式
fio --name=test --filename=/dev/sdb --rw=randread --bs=4k \
--size=1G --runtime=30 --ioengine=libaio --direct=1 \
--output=result.txt --output-format=json,normal
# 测试NFS共享
fio --name=nfs_test --filename=/mnt/nfs/testfile --rw=randread \
--bs=4k --size=10G --runtime=60 --ioengine=libaio \
--iodepth=16 --direct=1 --group_reporting
# 测试iSCSI LUN
fio --name=iscsi_test --filename=/dev/sdc --rw=randrw \
--bs=8k --size=50G --runtime=120 --ioengine=libaio \
--iodepth=32 --numjobs=4 --direct=1
| 指标 | 说明 | 单位 | 参考值 |
|---|---|---|---|
| BW (Bandwidth) | 带宽,单位时间内的数据传输量 | KB/s, MB/s | 越高越好 |
| IOPS | 每秒I/O操作数 | ops/s | 越高越好(特别是4K随机) |
| lat (Latency) | 延迟,I/O操作的响应时间 | μs, ms | 越低越好 |
| clat | 完成延迟(completion latency) | μs, ms | 越低越好 |
| slat | 提交延迟(submission latency) | μs, ms | 越低越好 |
| bw_mean | 平均带宽 | KB/s, MB/s | 稳定值 |
| iops_mean | 平均IOPS | ops/s | 稳定值 |
| 场景 | 块大小 | I/O类型 | 队列深度 | 目的 |
|---|---|---|---|---|
| HDD性能基准 | 1M | 顺序读/写 | 1-4 | 测试最大连续传输速度 |
| SSD性能基准 | 4K, 8K | 随机读/写 | 32-256 | 测试随机访问性能 |
| 数据库OLTP | 8K | 随机混合读写 | 64-256 | 模拟数据库负载 |
| 虚拟机存储 | 4K, 8K, 64K | 混合随机读写 | 32-128 | 测试虚拟化环境性能 |
| 视频流媒体 | 64K-1M | 顺序读 | 4-16 | 测试大文件连续读取 |
| 备份服务器 | 256K-1M | 顺序写 | 4-16 | 测试大文件写入性能 |
#!/bin/bash
# 自动化fio性能测试脚本
DEVICE="/dev/sdb"
OUTPUT_DIR="/var/log/fio_tests"
LOG_FILE="$OUTPUT_DIR/fio_results_$(date +%Y%m%d_%H%M%S).log"
TEST_DURATION=60
mkdir -p $OUTPUT_DIR
echo "=== fio性能测试报告 $(date) ===" > $LOG_FILE
echo "测试设备: $DEVICE" >> $LOG_FILE
echo "测试时长: ${TEST_DURATION}秒" >> $LOG_FILE
echo "" >> $LOG_FILE
# 测试函数
run_test() {
local test_name=$1
local rw_type=$2
local block_size=$3
local iodepth=$4
echo "运行测试: $test_name (${rw_type}, ${block_size}, iodepth=${iodepth})" | tee -a $LOG_FILE
fio --name="$test_name" --filename="$DEVICE" --rw="$rw_type" \
--bs="$block_size" --size=10G --runtime="$TEST_DURATION" \
--ioengine=libaio --iodepth="$iodepth" --direct=1 \
--group_reporting --output="$OUTPUT_DIR/${test_name}.log" \
--output-format=normal,json >> $LOG_FILE 2>&1
echo "----------------------------------------" >> $LOG_FILE
}
# 运行测试套件
echo "1. 顺序读写测试" >> $LOG_FILE
run_test "seq_read_1m" "read" "1M" 4
run_test "seq_write_1m" "write" "1M" 4
echo "2. 4K随机读写测试" >> $LOG_FILE
run_test "randread_4k" "randread" "4k" 32
run_test "randwrite_4k" "randwrite" "4k" 32
echo "3. 混合读写测试" >> $LOG_FILE
run_test "mixed_70r30w_4k" "randrw" "4k" 32
echo "4. 不同队列深度测试" >> $LOG_FILE
for depth in 1 4 8 16 32 64; do
run_test "randread_4k_depth${depth}" "randread" "4k" $depth
done
echo "测试完成!结果保存在: $OUTPUT_DIR" | tee -a $LOG_FILE
echo "详细报告: $LOG_FILE"
#!/bin/bash
# fio结果分析脚本
RESULTS_DIR="/var/log/fio_tests"
OUTPUT_FILE="/tmp/fio_summary_$(date +%Y%m%d).csv"
echo "Test Name,Read BW(MB/s),Write BW(MB/s),Read IOPS,Write IOPS,Read Latency(ms),Write Latency(ms)" > $OUTPUT_FILE
for logfile in $RESULTS_DIR/*.log; do
if [ -f "$logfile" ]; then
TEST_NAME=$(basename "$logfile" .log)
# 从日志文件中提取关键指标(简化版)
READ_BW=$(grep -A1 "READ:" "$logfile" | grep "bw=" | awk -F'=' '{print $2}' | awk '{print $1}')
WRITE_BW=$(grep -A1 "WRITE:" "$logfile" | grep "bw=" | awk -F'=' '{print $2}' | awk '{print $1}')
READ_IOPS=$(grep -A1 "READ:" "$logfile" | grep "iops=" | awk -F'=' '{print $2}' | awk '{print $1}')
WRITE_IOPS=$(grep -A1 "WRITE:" "$logfile" | grep "iops=" | awk -F'=' '{print $2}' | awk '{print $1}')
READ_LAT=$(grep -A1 "READ:" "$logfile" | grep "lat" | grep "avg=" | awk -F'=' '{print $2}' | awk '{print $1}')
WRITE_LAT=$(grep -A1 "WRITE:" "$logfile" | grep "lat" | grep "avg=" | awk -F'=' '{print $2}' | awk '{print $1}')
echo "$TEST_NAME,$READ_BW,$WRITE_BW,$READ_IOPS,$WRITE_IOPS,$READ_LAT,$WRITE_LAT" >> $OUTPUT_FILE
fi
done
echo "分析完成!结果已保存到: $OUTPUT_FILE"
echo ""
echo "=== 性能概览 ==="
cat $OUTPUT_FILE | column -t -s,
原因:libaio库未安装或内核不支持。
解决方案:
# 安装libaio库
# Ubuntu/Debian
sudo apt-get install libaio1 libaio-dev
# RHEL/CentOS
sudo yum install libaio libaio-devel
# 或者使用其他I/O引擎
--ioengine=sync # 同步I/O
--ioengine=posixaio # POSIX异步I/O
# 检查内核是否支持
lsmod | grep aio
cat /proc/sys/fs/aio-max-nr
直接测试块设备:
# 使用设备文件,不要挂载
# 首先卸载设备
sudo umount /dev/sdb
# 直接测试整个磁盘
fio --name=disk_test --filename=/dev/sdb --rw=randread \
--bs=4k --size=100% --runtime=60 --ioengine=libaio \
--direct=1 --group_reporting
# 注意:
# 1. 使用 --size=100% 测试整个设备
# 2. 确保设备上没有重要数据
# 3. 可能需要使用--offset参数跳过某些区域
可能原因和优化方法:
--iodepth=32 或更高--numjobs=4--ioengine=libaio--direct=1--bs=4k(随机测试)cat /sys/block/sdb/queue/scheduler
# 对于SSD,使用noop或deadline
echo noop > /sys/block/sdb/queue/scheduler
--direct=1绕过缓存获得真实磁盘性能--direct参数(可能导致缓存影响结果)bonnie++文件系统性能基准测试
iozone文件系统基准测试工具
hdparm磁盘读取性能测试
dd简单的磁盘复制和测试