blktrace介绍和使用指南。
1.blktrace是什么?
blktrace是 Linux 下用于跟踪block layer I/O 行为的工具。
它可以记录一个块设备上的 I/O 从进入 block layer 到完成之间的各种事件,例如:
- I/O 何时进入队列
- 是否发生 merge
- 何时下发到 driver/device
- 何时完成
- I/O 类型是 read、write、flush、discard
- sector、大小、进程名、PID、CPU 等信息
常用于:
| 场景 | 用途 |
|---|---|
| SSD 性能分析 | 观察真实 I/O pattern、队列行为、latency |
| fio workload 验证 | 确认 fio 是否按预期下发 I/O |
| 延迟尖峰分析 | 定位 block layer 哪个阶段耗时 |
| I/O merge 分析 | 查看随机/顺序 I/O 是否被合并 |
| queue depth 分析 | 判断实际是否打满设备 |
| kernel / driver 调试 | 分析 request 生命周期 |
2. 常用工具组件
blktrace通常和下面几个工具一起使用:
| 工具 | 作用 |
|---|---|
blktrace | 采集 block trace |
blkparse | 解析 blktrace 输出 |
btt | Block Trace Toolkit,分析延迟、队列、seek 等 |
iowatcher | 生成 I/O 可视化图表,部分系统可能没有安装 |
安装方式通常是:
sudoaptinstallblktrace或:
sudoyuminstallblktrace3. 基本使用流程
3.1 采集 3 秒 trace
推荐使用完整设备路径:
sudoblktrace-w3-d/dev/nvme0n1参数说明:
| 参数 | 含义 |
|---|---|
-w 3 | 采集 3 秒 |
-d /dev/nvme0n1 | 指定被跟踪的 block device |
执行后会在当前目录生成多个文件,例如:
nvme0n1.blktrace.0 nvme0n1.blktrace.1 nvme0n1.blktrace.2 ...这些是 per-CPU trace 文件。
3.2 解析 trace
blkparse-invme0n1这里的nvme0n1是输入文件前缀,blkparse会自动读取:
nvme0n1.blktrace.*3.3 保存解析结果
blkparse-invme0n1|teeblkparse_nvme0n1.log如果还想生成 binary dump,用于后续btt分析:
blkparse-invme0n1-dblkparse_nvme0n1.bin|teeblkparse_nvme0n1.log注意:
-dblkparse_nvme0n1.bin这里的-d是让blkparse输出一个二进制 dump 文件,不是指定 device。
4. 推荐标准命令
你的场景可以写成这样:
sudoblktrace-w3-d/dev/nvme0n1-onvme0n1sudoblkparse-invme0n1\-d../blkparse_nvme0n1.bin\|tee-a../blkparse_nvme0n1.log说明:
| 命令 | 说明 |
|---|---|
-o nvme0n1 | 指定输出文件前缀 |
blkparse -i nvme0n1 | 读取nvme0n1.blktrace.* |
-d ../blkparse_nvme0n1.bin | 生成二进制 trace dump |
tee -a | 追加保存文本 log |
5. 脚本化使用示例
建议每次采集放到独立目录,避免旧文件混淆。
#!/bin/bashdev=nvme0n1duration=3outdir=../blktrace_${dev}_$(date+%Y%m%d_%H%M%S)mkdir-p"$outdir"echo"Collecting blktrace for /dev/$dev, duration=${duration}s"sudoblktrace-w"$duration"-d/dev/$dev-o"$outdir/$dev"echo"Parsing trace..."sudoblkparse-i"$outdir/$dev"\-d"$outdir/blkparse_${dev}.bin"\|tee"$outdir/blkparse_${dev}.log"echo"Done. Output directory:$outdir"运行:
bashrun_blktrace.sh输出类似:
../blktrace_nvme0n1_20260804_093000/ ├── nvme0n1.blktrace.0 ├── nvme0n1.blktrace.1 ├── nvme0n1.blktrace.2 ├── blkparse_nvme0n1.bin └── blkparse_nvme0n1.log6. 实时解析模式
如果不想保存中间 trace 文件,可以直接:
sudoblktrace-d/dev/nvme0n1-o-|blkparse-i-采集指定时间:
sudoblktrace-w3-d/dev/nvme0n1-o-|blkparse-i-保存 log:
sudoblktrace-w3-d/dev/nvme0n1-o-\|blkparse-i-\|teeblkparse_nvme0n1.log这种方式适合快速看结果,但如果后续要用btt分析,建议保存 binary dump。
7.blkparse输出怎么看?
典型输出类似:
8,0 0 1 0.000000000 1234 Q WS 123456 + 8 [fio] 8,0 0 2 0.000001234 1234 G WS 123456 + 8 [fio] 8,0 0 3 0.000002345 1234 I WS 123456 + 8 [fio] 8,0 0 4 0.000003456 1234 D WS 123456 + 8 [fio] 8,0 0 5 0.000123456 1234 C WS 123456 + 8 [0]字段大致含义:
| 字段 | 示例 | 含义 |
|---|---|---|
| device | 8,0 | major, minor |
| CPU | 0 | 事件发生的 CPU |
| sequence | 1 | 事件序号 |
| timestamp | 0.000000000 | 时间戳,单位秒 |
| PID | 1234 | 进程 ID |
| action | Q/G/I/D/C | block event |
| RWBS | WS | I/O 类型 |
| sector | 123456 | 起始 sector |
| size | + 8 | sector 数量 |
| process | [fio] | 进程名 |
8. 常见 action 含义
blkparse中最重要的是 action 字段。
| Action | 含义 | 说明 |
|---|---|---|
Q | Queue | I/O 进入 block layer |
G | Get request | 分配 request |
I | Insert | 插入 I/O scheduler / request queue |
D | Issue / Dispatch | 下发到 driver/device |
C | Complete | I/O 完成 |
M | Back merge | 和前面的 request 合并 |
F | Front merge | 和后面的 request 合并 |
B | Bounced | bounce buffer |
A | Remap | I/O 被 remap |
X | Split | I/O 被拆分 |
通常分析 latency 时最关注:
Q -> D -> C或者更细:
Q -> G -> I -> D -> C9. RWBS 字段怎么看?
RWBS 表示 I/O 类型和属性。
常见值:
| RWBS | 含义 |
|---|---|
R | Read |
W | Write |
D | Discard / TRIM |
F | Flush |
A | Readahead |
S | Sync |
M | Metadata |
N | FUA / Force Unit Access,取决于内核版本显示 |
例如:
WS一般表示:
- Write
- Sync
RA表示:
- Read
- Readahead
10. 用btt分析延迟
如果你生成了 binary dump:
blkparse-invme0n1-dblkparse_nvme0n1.bin可以用:
btt-iblkparse_nvme0n1.bin-obtt_nvme0n1它会生成一组文件,例如:
btt_nvme0n1.avg btt_nvme0n1.dat btt_nvme0n1.q2c btt_nvme0n1.d2c ...常见 latency 缩写:
| 缩写 | 含义 |
|---|---|
Q2Q | Queue to Queue |
Q2G | Queue to Get request |
G2I | Get request to Insert |
I2D | Insert to Dispatch |
D2C | Dispatch to Complete |
Q2C | Queue to Complete,总 block layer 视角延迟 |
对 SSD 性能分析来说,比较常看:
| 指标 | 说明 |
|---|---|
Q2C | 应用到 block complete 的整体延迟 |
D2C | request 下发到设备后,到完成的时间 |
I2D | 在 scheduler / queue 中等待的时间 |
| queue depth | 是否真的把设备压满 |
11. 常用场景示例
11.1 验证 fio I/O size
先运行 fio,例如:
fio--name=randread\--filename=/dev/nvme0n1\--direct=1\--rw=randread\--bs=4k\--iodepth=32\--numjobs=1\--runtime=30\--time_based=1\--ioengine=libaio同时采集:
sudoblktrace-w5-d/dev/nvme0n1-onvme0n1 blkparse-invme0n1|teeblkparse.log看输出中类似:
R 123456 + 8因为一个 sector 通常是 512 bytes:
8 sectors * 512 bytes = 4096 bytes = 4 KiB所以+ 8对应 4 KiB I/O。
11.2 查看 read/write 数量
grep" R "blkparse_nvme0n1.log|wc-lgrep" W "blkparse_nvme0n1.log|wc-l不过更准确时建议筛选 Complete 事件:
grep" C "blkparse_nvme0n1.log|grep" R "|wc-lgrep" C "blkparse_nvme0n1.log|grep" W "|wc-l11.3 查看是否有 merge
grep" M "blkparse_nvme0n1.loggrep" F "blkparse_nvme0n1.log如果大量顺序 I/O 被合并,可能看到很多M或F事件。
11.4 查看 flush
grep" F"blkparse_nvme0n1.log也可以看 RWBS 字段是否有 flush 相关标记。
11.5 分析 tail latency
先生成 btt 输出:
btt-iblkparse_nvme0n1.bin-obtt_nvme0n1然后查看q2c或d2c相关文件。
也可以从blkparse文本中自己解析Q和C对应 request 的时间差,不过这需要根据 sector、sequence、request 生命周期做匹配,建议优先使用btt。
12. 过滤指定事件
blktrace支持-a指定 action mask。
例如只采集 read/write:
sudoblktrace-w3-d/dev/nvme0n1-aread-awrite-onvme0n1常见可用类别包括:
read write barrier sync queue requeue issue complete fs pc notify drv_data不同内核版本支持项可能略有差异,可以查看:
manblktrace13. 注意事项和常见坑
13.1 设备名建议使用完整路径
不推荐:
blktrace-dnvme0n1推荐:
sudoblktrace-d/dev/nvme0n113.2 需要 root 权限
通常需要:
sudoblktrace...否则可能报权限错误。
13.3 会生成多个 per-CPU 文件
例如:
nvme0n1.blktrace.0 nvme0n1.blktrace.1 ...不要只拷贝其中一个文件,否则解析不完整。
13.4 多次运行容易混淆旧文件
建议每次采集前清理:
rm-fnvme0n1.blktrace.*或者使用独立目录:
mkdirtrace_$(date+%Y%m%d_%H%M%S)13.5 blktrace 看到的是 block layer,不是 NVMe protocol trace
blktrace可以告诉你:
- block I/O 什么时间下发
- sector/size 是什么
- 什么时候完成
- block layer 是否 merge/split
但它不能直接告诉你:
- NVMe command DW 字段
- SQ/CQ doorbell 细节
- controller 内部 firmware 行为
- NAND 层 latency
如果要看 NVMe command level,可能需要:
- ftrace / trace-cmd 的 nvme tracepoints
- perf
- kernel dynamic debug
- PCIe analyzer
- firmware internal trace
13.6 NVMe 多队列下事件分布在多个 CPU
NVMe 是 blk-mq 多队列模型,I/O 可能分布在多个 CPU trace 文件里。解析时一定用:
blkparse-invme0n1不要只分析单个:
nvme0n1.blktrace.014. 一个完整例子:fio + blktrace + btt
dev=nvme0n1outdir=blktrace_${dev}_$(date+%Y%m%d_%H%M%S)mkdir-p"$outdir"# 后台采集 10 秒sudoblktrace-w10-d/dev/$dev-o"$outdir/$dev"&# 等待 blktrace 准备sleep1# 跑 fio workloadsudofio--name=test\--filename=/dev/$dev\--direct=1\--rw=randread\--bs=4k\--iodepth=32\--numjobs=1\--runtime=8\--time_based=1\--ioengine=libaio\--group_reportingwait# 解析sudoblkparse-i"$outdir/$dev"\-d"$outdir/blkparse_${dev}.bin"\|tee"$outdir/blkparse_${dev}.log"# btt 分析btt-i"$outdir/blkparse_${dev}.bin"-o"$outdir/btt_${dev}"echo"Output:$outdir"15. 简单结论
如果只是快速采集和解析,可以用:
sudoblktrace-w3-d/dev/nvme0n1-onvme0n1sudoblkparse-invme0n1\-dblkparse_nvme0n1.bin\|teeblkparse_nvme0n1.log如果要做 SSD 性能/延迟分析,建议再加:
btt-iblkparse_nvme0n1.bin-obtt_nvme0n1重点关注:
Q -> C:整体 I/O 延迟D -> C:设备/driver 完成延迟- I/O size:例如
+8sectors = 4 KiB - merge/split:是否改变了 workload pattern
- queue depth:是否真正压到 SSD 上了
