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 输出
bttBlock Trace Toolkit,分析延迟、队列、seek 等
iowatcher生成 I/O 可视化图表,部分系统可能没有安装

安装方式通常是:

sudoaptinstallblktrace

或:

sudoyuminstallblktrace

3. 基本使用流程

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.log

6. 实时解析模式

如果不想保存中间 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]

字段大致含义:

字段示例含义
device8,0major, minor
CPU0事件发生的 CPU
sequence1事件序号
timestamp0.000000000时间戳,单位秒
PID1234进程 ID
actionQ/G/I/D/Cblock event
RWBSWSI/O 类型
sector123456起始 sector
size+ 8sector 数量
process[fio]进程名

8. 常见 action 含义

blkparse中最重要的是 action 字段。

Action含义说明
QQueueI/O 进入 block layer
GGet request分配 request
IInsert插入 I/O scheduler / request queue
DIssue / Dispatch下发到 driver/device
CCompleteI/O 完成
MBack merge和前面的 request 合并
FFront merge和后面的 request 合并
BBouncedbounce buffer
ARemapI/O 被 remap
XSplitI/O 被拆分

通常分析 latency 时最关注:

Q -> D -> C

或者更细:

Q -> G -> I -> D -> C

9. RWBS 字段怎么看?

RWBS 表示 I/O 类型和属性。

常见值:

RWBS含义
RRead
WWrite
DDiscard / TRIM
FFlush
AReadahead
SSync
MMetadata
NFUA / 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 缩写:

缩写含义
Q2QQueue to Queue
Q2GQueue to Get request
G2IGet request to Insert
I2DInsert to Dispatch
D2CDispatch to Complete
Q2CQueue to Complete,总 block layer 视角延迟

对 SSD 性能分析来说,比较常看:

指标说明
Q2C应用到 block complete 的整体延迟
D2Crequest 下发到设备后,到完成的时间
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-l

11.3 查看是否有 merge

grep" M "blkparse_nvme0n1.loggrep" F "blkparse_nvme0n1.log

如果大量顺序 I/O 被合并,可能看到很多MF事件。


11.4 查看 flush

grep" F"blkparse_nvme0n1.log

也可以看 RWBS 字段是否有 flush 相关标记。


11.5 分析 tail latency

先生成 btt 输出:

btt-iblkparse_nvme0n1.bin-obtt_nvme0n1

然后查看q2cd2c相关文件。

也可以从blkparse文本中自己解析QC对应 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

不同内核版本支持项可能略有差异,可以查看:

manblktrace

13. 注意事项和常见坑

13.1 设备名建议使用完整路径

不推荐:

blktrace-dnvme0n1

推荐:

sudoblktrace-d/dev/nvme0n1

13.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.0

14. 一个完整例子: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 上了