Linux fio 磁盘测试工具介绍

发布时间: 更新时间: 总字数:1825 阅读时间:4m 作者:IP:上海 网址

fio (Flexible I/O Tester) 是目前 Linux 下最专业、最灵活的磁盘性能测试工具。由 Linux 内核 IO 维护者 Jens Axboe 编写,它能模拟各种复杂的 IO 场景(顺序/随机、读/写、混合、队列深度、不同的 IO 引擎等)。相比 iozonefio 的输出更详尽(尤其是延迟分布),更能反映现代 SSD 和高性能存储的特性。

FIO 核心参数简介

在写脚本之前,先了解几个关键参数,防止测试结果“自欺欺人”:

  • -ioengine=libaio: Linux 原生异步 I/O 引擎,测试磁盘性能的标准选择(比 sync 引擎强)。
  • -direct=1: 最重要参数。绕过 Linux Page Cache,直接测试磁盘硬件性能。
  • -bs (Block Size): 块大小(本次测试的核心变量,如 4k, 1M)。
  • -rw: 读写模式。
    • read / write: 顺序读 / 顺序写(通常用于大块 1M+)。
    • randread / randwrite: 随机读 / 随机写(通常用于小块 4k/8k)。
  • -iodepth: 队列深度。SSD 通常需要高队列(如 32, 64)才能跑满性能;HDD 通常低队列(1, 4)。
  • -numjobs: 并发线程数。

全自动化测试脚本

为了满足你的需求,我编写了一个 Shell 脚本。 逻辑设计:

  • 小块 (4k, 8k): 测试 随机读写 (Random),关注 IOPS 和延迟。
  • 大块 (1M - 16M): 测试 顺序读写 (Sequential),关注 吞吐量 (Bandwidth)。

请将以下内容保存为 fio_bench.sh,赋予执行权限 chmod +x fio_bench.sh

bash
#!/bin/bash

# ================= 配置区域 =================
# 测试文件存放路径(请确保该分区有足够空间,且不要在系统盘根目录运行以免影响系统)
TEST_DIR="/data"           # 请修改为你挂载的磁盘路径,例如 /mnt/nvme01
TEST_FILE="$TEST_DIR/fio_test_file"

# 测试文件大小 (如果内存很大,建议设大一点,或者依靠 direct=1 绕过缓存)
SIZE="2G"

# 运行时间 (基于时间测试,避免大文件跑太久)
RUNTIME=30

# 测试的块大小列表
BLOCK_SIZES=("4k" "8k" "1M" "2M" "4M" "8M" "16M")

# ===========================================

# 检查目录是否存在
if [ ! -d "$TEST_DIR" ]; then
    echo "Error: 目录 $TEST_DIR 不存在,请修改脚本中的 TEST_DIR 变量。"
    exit 1
fi

echo "=============================================="
echo "开始 FIO 性能测试"
echo "测试路径: $TEST_FILE"
echo "文件大小: $SIZE"
echo "每项时长: $RUNTIME 秒"
echo "=============================================="
echo ""

for BS in "${BLOCK_SIZES[@]}"; do
    echo "----------------------------------------------"
    echo "正在测试块大小: $BS"

    # 判断读写模式:小块测随机,大块测顺序
    if [[ "$BS" == "4k" || "$BS" == "8k" ]]; then
        RW_MODES=("randread" "randwrite")
        TYPE_LABEL="随机(Random)"
    else
        RW_MODES=("read" "write")
        TYPE_LABEL="顺序(Sequential)"
    fi

    for RW in "${RW_MODES[@]}"; do
        echo "  -> 正在运行: $TYPE_LABEL - $RW ..."

        # 运行 FIO
        # -group_reporting: 汇总多线程结果
        # -time_based: 强制运行指定时间,忽略文件是否读写完
        OUTPUT=$(fio --name=fio_test \
            --filename="$TEST_FILE" \
            --ioengine=libaio \
            --direct=1 \
            --thread \
            --numjobs=1 \
            --iodepth=32 \
            --rw="$RW" \
            --bs="$BS" \
            --size="$SIZE" \
            --runtime="$RUNTIME" \
            --time_based \
            --group_reporting \
            --allow_mounted_write=1)

        # 提取关键结果 (IOPS 和 带宽)
        # 注意:不同 fio 版本的输出格式微略有不同,以下 grep 适用于大多数版本

        # 提取 IOPS (例如: IOPS=15.2k)
        IOPS=$(echo "$OUTPUT" | grep -E "IOPS=" | awk -F, '{print $1}' | awk -F= '{print $2}')

        # 提取 带宽 BW (例如: BW=59.5MiB/s)
        BW=$(echo "$OUTPUT" | grep -E "bw=" | awk -F, '{print $2}' | awk -F= '{print $2}')

        # 提取 平均延迟 lat (usec) - 提取 clat avg
        LAT=$(echo "$OUTPUT" | grep -A 3 "clat (" | grep "avg=" | awk -F, '{print $3}' | awk -F= '{print $2}')

        echo "     结果: IOPS: $IOPS | 带宽: $BW | 平均延迟: ${LAT}us"
    done
done

# 清理测试文件
rm -f "$TEST_FILE"
echo "----------------------------------------------"
echo "测试结束,清理临时文件完成。"

运行脚本与输出示例

运行脚本:

bash
sudo ./fio_bench.sh

屏幕会实时输出简化的结果,类似:

text
正在测试块大小: 4k
  -> 正在运行: 随机(Random) - randread ...
     结果: IOPS: 45.2k | 带宽: 177MiB/s | 平均延迟: 705.12us
  -> 正在运行: 随机(Random) - randwrite ...
     结果: IOPS: 30.1k | 带宽: 118MiB/s | 平均延迟: 1050.55us
----------------------------------------------
正在测试块大小: 1M
  -> 正在运行: 顺序(Sequential) - read ...
     结果: IOPS: 2500 | 带宽: 2500MiB/s | 平均延迟: 12000.00us
...

详细结果解析(如何看 FIO 原文报告)

虽然脚本提取了摘要,但如果需要深度分析,你需要看 FIO 的完整输出。以下是一个典型输出片段及三大核心指标解析:

text
Jobs: 1 (f=1): [r(1)][100.0%][r=512MiB/s,w=0KiB/s][r=131k,w=0 IOPS][eta 00m:00s]
...
   read: IOPS=131k, BW=512MiB/s (537MB/s)(15.0GiB/30001msec)
    slat (usec): min=2, max=65, avg= 3.96, stdev= 1.76
    clat (usec): min=54, max=12032, avg=241.36, stdev=69.87
     lat (usec): min=59, max=12035, avg=245.54, stdev=70.01
    ...
    clat percentiles (usec):
     |  1.00th=[  133],  5.00th=[  151], 10.00th=[  163], 20.00th=[  180],
     | 30.00th=[  195], 40.00th=[  210], 50.00th=[  227], 60.00th=[  249],
     | 70.00th=[  273], 80.00th=[  302], 90.00th=[  338], 95.00th=[  367],
     | 99.00th=[  420], 99.50th=[  449], 99.90th=[  611], 99.95th=[  725],
     | 99.99th=[ 2278]

1. IOPS (每秒 I/O 次数)

  • 位置: read: IOPS=131k
  • 关注点:
    • 4k/8k 块大小时,这是唯一核心指标。
    • SATA SSD 通常在 5k-80k 左右。
    • NVMe SSD 通常在 100k-1000k (1M) 左右。
    • 如果是数据库业务,IOPS 越高越好。

2. BW (带宽/吞吐量)

  • 位置: BW=512MiB/s
  • 关注点:
    • 1M/2M/4M… 大块时,这是核心指标。
    • 反映了拷贝大文件、流媒体处理的速度。
    • PCIe 3.0 NVMe 约为 2000-3500 MB/s;PCIe 4.0 可达 7000 MB/s。

3. Latency (延迟) - 最专业的指标

  • 位置: clat percentiles (usec) (Completing Latency)
  • 解析:
    • slat: 提交延迟 (Submission Latency),通常很低,不重要。
    • clat: 完成延迟 (从提交到完成的时间),这是真正的磁盘响应时间
    • lat: 总延迟 (slat + clat)。
  • 百分位 (Percentiles) 怎么看:
    • 不要只看 Avg (平均值),要看 95.00th99.00th
    • 99.00th=[ 420] 意味着:99% 的 I/O 请求都在 420 微秒内完成了。
    • 如果 99.99th 突然变得非常高(例如几百毫秒),说明磁盘出现了长尾延迟(抖动),这会导致业务卡顿。

总结

  • 4k, 8k: 看 IOPSclat 99th(适合数据库、小文件服务器性能评估)。
  • 1M - 16M: 看 BW(适合视频剪辑、日志归档、大数据存储评估)。