目录
1. 目录结构重组
改动前
改动后
2. 每次运行产生独立时间戳目录
3. fio 通用执行封装(fio_runner.sh)
4. lib/logging.sh — 统一日志函数
5. lib/device.sh — 设备验证与容量查询
6. lib/smart.sh — SMART 数据采集
7. lib/fio_utils.sh — JSON 结果解析
8. phases/fob.sh — FOB 基线
9. phases/precondition.sh — 预处理
10. phases/steady_state.sh — 稳态判断
11. phases/measurement.sh 拆分
12. phases/report.sh — 汇总报告
13. 错误处理加固
14. 环境变量汇总
1. 目录结构重组
改动前
所有脚本平铺在scripts/下,输出目录固定为/tmp/jesd218/,
每次运行会覆盖上次结果。
改动后
scripts/ ├── run_tests.sh # 入口,编排全流程 ├── fio_runner.sh # 通用 fio 执行封装 ├── lib/ │ ├── logging.sh # 日志函数(log_info / log_warn / log_error) │ ├── device.sh # 设备验证、容量查询 │ ├── fio_utils.sh # fio JSON 结果解析工具 │ └── smart.sh # SMART 数据采集 └── phases/ ├── fob.sh # Fresh-Out-of-Box 基线 ├── precondition.sh # 预处理(顺序写全盘两遍) ├── steady_state.sh # 稳态判断 ├── seq_write.sh # 顺序写测量 ├── rand_write.sh # 随机写测量 ├── mixed_rw.sh # 混合读写测量 └── report.sh # 汇总报告生成每次运行的输出挂在带时间戳的独立目录下:
/tmp/jesd218/20250714_153022/ ├── logs/ # fio bw/iops/lat 日志根 │ ├── fob/ │ ├── precondition/ │ ├── steady_state/ │ ├── seq_write/ │ ├── rand_write/ │ └── mixed_rw/ ├── fob/ # JSON 结果、SMART 快照 ├── precondition/ ├── seq_write/ ├── rand_write/ ├── mixed_rw/ ├── test_metadata.json └── report/ ├── summary.json └── summary.txt2. 每次运行产生独立时间戳目录
文件:scripts/run_tests.sh
# 改动前 TEST_DIR="/tmp/jesd218/$(date +%Y%m%d_%H%M%S)" LOG_DIR="${LOG_DIR:-/tmp/jesd218/logs}" # 固定路径,多次运行互相覆盖 改动后 TEST_DIR="/tmp/jesd218/$(date +%Y%m%d_%H%M%S)" LOG_DIR="${LOG_DIR:-${TEST_DIR}/logs}" # 跟随 TEST_DIR,每次运行独立效果:TEST_DIR与LOG_DIR共用同一时间戳,结果文件和 fio 日志始终一一对应。
手动通过环境变量传入LOG_DIR时行为不变。
3. fio 通用执行封装(fio_runner.sh)
新增scripts/fio_runner.sh,统一处理:
- 接收参数:
<output_dir> <log_prefix> <fio_args...> - 自动创建输出目录
- 将
--output-format=json结果写入<output_dir>/result.json - 将
--write_bw_log/--write_iops_log/--write_lat_log写入LOG_DIR/<log_prefix>/ - 捕获 fio 退出码,非零时打印错误并向上透传
各阶段脚本不再各自拼接 fio 参数,统一调用fio_runner.sh。
4. lib/logging.sh — 统一日志函数
新增scripts/lib/logging.sh,提供:
| 函数 | 输出格式 |
|---|---|
log_info | [INFO] YYYY-MM-DD HH:MM:SS <message> |
log_warn | [WARN] YYYY-MM-DD HH:MM:SS <message> |
log_error | [ERROR] YYYY-MM-DD HH:MM:SS <message> |
所有阶段脚本source此文件,不再使用裸echo。
5. lib/device.sh — 设备验证与容量查询
新增scripts/lib/device.sh,提供:
validate_device <dev>:检查设备存在、是块设备、可读写get_device_size_gb <dev>:返回设备容量(GiB,整数)get_device_model <dev>:从/sys或hdparm读取型号字符串
run_tests.sh在启动阶段调用validate_device,失败则立即退出。
6. lib/smart.sh — SMART 数据采集
新增scripts/lib/smart.sh,提供:
collect_smart <dev> <output_file>:调用smartctl -a -j并写入 JSON- 在 FOB、预处理前后、各测量阶段前后各采集一次,存入对应阶段目录
7. lib/fio_utils.sh — JSON 结果解析
新增scripts/lib/fio_utils.sh,提供:
parse_bw_mbps <result.json> <rw>:提取带宽(MB/s)parse_iops <result.json> <rw>:提取 IOPSparse_lat_us <result.json> <rw> <percentile>:提取延迟百分位(µs)
report.sh调用这些函数汇总各阶段结果,不再用grep/awk手工解析。
8. phases/fob.sh — FOB 基线
- 顺序读 + 顺序写各一轮,块大小 128 KiB,队列深度 32
- 结果写入
$TEST_DIR/fob/ - 采集测试前后 SMART
9. phases/precondition.sh — 预处理
- 顺序写全盘两遍(JESD218 要求)
- 块大小 128 KiB,队列深度 32
- 每遍结束后采集 SMART,记录写入量
10. phases/steady_state.sh — 稳态判断
- 对随机写 4 KiB QD32 连续测量,每轮 60 秒,最多 25 轮
- 用最近 5 轮 IOPS 的极差 / 均值 < 10% 判定稳态
- 未收敛时打印
[WARN]并继续(不中止测试)
11. phases/measurement.sh 拆分
原measurement.sh拆分为三个独立阶段脚本,各自可单独运行或重跑:
| 脚本 | 测试内容 |
|---|---|
seq_write.sh | 顺序写,块大小 512B / 4K / 8K / 16K / 64K / 128K / 512K / 1M |
rand_write.sh | 随机写,块大小同上,QD1 / QD4 / QD8 / QD16 / QD32 |
mixed_rw.sh | 混合读写,读写比 100:0 / 65:35 / 50:50 / 35:65 / 0:100 |
12. phases/report.sh — 汇总报告
生成两份文件到$TEST_DIR/report/:
summary.json:机器可读,包含所有阶段的 IOPS / 带宽 / 延迟关键值summary.txt:人类可读的表格形式,便于快速查阅
13. 错误处理加固
run_tests.sh顶部加set -euo pipefail- 各阶段脚本对 fio 退出码显式检查
- 设备验证失败、目录创建失败均立即退出并打印
[ERROR] - SMART 采集失败只打印
[WARN],不中止流程(smartctl 不一定可用)
14. 环境变量汇总
| 变量 | 默认值 | 说明 |
|---|---|---|
DEVICE | 必填 | 待测块设备,如/dev/sda |
TEST_DIR | /tmp/jesd218/<timestamp> | 本次运行根目录 |
LOG_DIR | $TEST_DIR/logs | fio 日志根目录 |
RUNTIME | 60 | 每轮测量时长(秒) |
SS_ROUNDS | 25 | 稳态最大轮次 |
SS_WINDOW | 5 | 稳态判断窗口大小 |
SS_THRESHOLD | 0.1 | 稳态极差/均值阈值 |
SKIP_PRECONDITION | 0 | 设为1跳过预处理 |
SKIP_SMART | 0 | 设为1跳过 SMART 采集 |
文档已写入docs/changelog.md,按主题分了 14 节:
- 目录结构重组(
lib/+phases/分层) - 时间戳目录改动(本次改动,
LOG_DIR跟随TEST_DIR) fio_runner.sh通用封装lib/logging.sh统一日志函数lib/device.sh设备验证lib/smart.shSMART 采集lib/fio_utils.shJSON 解析
8-11. 各测量阶段脚本(FOB / 预处理 / 稳态 / 测量拆分)report.sh汇总报告- 错误处理加固
- 所有环境变量清单
往期相关文章
更多关于 SSD 性能测试与 FIO 实战的内容,欢迎阅读我的 CSDN 往期文章:
- SSD FIO顺序读性能解析
- SSD FIO顺序写性能解析
- SSD FIO随机读性能解析
- SSD FIO随机写性能解析
- SSD 性能解析:原理、流程、场景与问题排查
- Linux NVMe 中断排查与性能优化:NUMA 实战
- Linux NVMe 中断排查与性能优化:CPU 亲和性
- 企业级 SSD 耐久度评测(JESD218 / JESD219 + FIO)
- 企业级 SSD 性能评测:稳态、尾延迟与 fio 实测命令-CSDN博客
- Fio 从旧版脚本引用版本升级至 v3.43 的问题排查与经验积累-CSDN博客