直接用 iostat -x 1 实时查看 rrqm/s 和 wrqm/s,二者是 iostat -x 中唯一直接反映 IO 合并行为的字段,表示每秒被调度器合并掉的读/写请求数,非合并后减少量;值为 0 不代表无合并,需结合 blktrace 验证真实合并。

怎么直接看 rrqm/s 和 wrqm/s 这两个关键指标
用 iostat -x 1 就能实时看到每秒合并的读/写请求数,rrqm/s 和 wrqm/s 是唯一直接反映 IO 合并行为的字段。注意必须加 -x(扩展模式),否则默认输出里根本没有这两个列。
常见误区是只跑 iostat 1 或 iostat -d,结果找不到 rrqm/s —— 它只存在于 -x 输出中。另外,这些值是“被调度器合并掉的次数”,不是“合并后减少的请求数”,所以即使数值小也不代表没合并。
- 首次运行前确保已安装 sysstat 包:
sudo apt install sysstat(Debian/Ubuntu)或sudo yum install sysstat(RHEL/CentOS) - 如果设备名不显示(比如只看到
dm-0而非sda),说明 IO 走的是 LVM 或加密层,要盯住实际后端设备(如/dev/mapper/vg-lv对应的dm-0) - 值持续为 0 不代表没合并,可能是队列太浅、IO 地址太分散,或请求刚进队就立刻派发
为什么不能只信 fdisk -l 的 Sector size 行
fdisk -l 显示的 “Sector size (logical/physical): 512 bytes / 4096 bytes” 是估算值,不是内核实际使用的逻辑扇区大小。它依赖固件返回和 CHS/LBA 解析,部分 USB 桥接盘或 NVMe 设备会硬报 512,哪怕物理粒度是 4K。
真正该信的是 blockdev --getss:它绕过所有中间层,直调 BLKSSZGET ioctl,返回内核块层声明的逻辑扇区字节数。这才是 IO 合并对齐计算的基准。
- 必须用
sudo blockdev --getss /dev/sda,普通用户无权打开裸设备节点 - 不能对分区运行(如
/dev/sda1),只接受整块磁盘设备路径 - 若返回
Operation not permitted,大概率是权限问题;若返回No such file or directory,检查设备名是否拼错(sdb≠sdb1,nvme0n1≠nvm0n1p1)
怎么验证合并是否真实发生,而不是数字幻觉
rrqm/s 数值本身不可靠,尤其在 writeback 模式下:大量 write 系统调用被延迟提交,iostat 统计的是最终下发到块层的 request,不是应用层发起的 syscall。更可靠的验证方式是抓取底层事件流。
用 blktrace 看实际合并标记:sudo blktrace -d /dev/sda -w 5 -o - | blkparse | grep 'M'。只要输出里有带 M(merged)的行,就说明前向或后向合并确实发生了。
- 该命令需 root 权限,且会短暂影响 I/O 性能,别在生产高峰跑
- 如果目标设备是 LVM 逻辑卷(如
dm-0),要 trace 对应的dm-0,不是底层sda - NVMe 设备因多队列设计,每个 CPU 队列独立处理,
nomerges设置只作用于单个 queue,全局rrqm/s可能仍不为 0
哪些 iostat -x 字段能间接佐证合并效果
合并的最终效果体现在请求形态上,avgrq-sz、avgqu-sz、r_await/w_await 这几个字段比 rrqm/s 更能说明问题。
avgrq-sz(平均请求大小,单位扇区)最直观:合并越多,这个值通常越大。HDD 上长期 >64(即 >32KB)较常见;若始终卡在 8(4KB),说明 IO 极其离散,合并基本失效。
-
avgqu-sz过低(比如 r/s 很高,提示 IO 请求过于随机,无法排队合并 -
r_await或w_await显著低于历史均值,且rrqm/s同步上升,大概率是合并生效了 - 不要单独看
rrqm/s是否变大,要结合avgrq-sz和await一起判断——三者趋势一致才可信
合并的真实性和有效性,取决于你用什么数据说话。数值指标容易受缓存、队列深度、硬件类型干扰,blktrace 的 M 标记和 blockdev --getss 的返回值,才是绕过所有中间层的硬依据。


















