如何监控NVMe SSD的IO队列深度 解决iostat avgqu-sz为0问题
NVMe SSD IO队列深度监控方法
在NVMe SSD上开展数据库基准测试,需要监控IO队列在途请求数随时间的变化、判断数据库是否充分利用IO队列能力时,常遇到iostat输出avgqu-sz字段恒为0的现象,该现象的根因是NVMe采用了和传统SATA SSD完全不同的存储栈架构:
- 传统SATA SSD走旧版单队列块存储栈,旧版
iostat(属于sysstat工具集)读取/sys/block/<设备名>/stat的旧统计字段计算平均队列深度,在单队列栈下数据准确 - NVMe SSD默认采用blk-mq多队列存储栈,内核4.x早期版本、版本号低于12.1.0的sysstat包未适配blk-mq统计逻辑,读取到的队列深度值恒为0,无参考意义。
可行的监控方案
1. 升级sysstat后直接用iostat查看
将sysstat升级到12.1.0及以上版本,新版本已完成blk-mq适配,执行以下命令即可查看准确的队列统计:
iostat -x 1 nvme0n1
注意新版本输出中对应队列深度的字段名从旧版的avgqu-sz调整为aqu-sz,不要找错字段。
2. 无升级条件时读取内核原生统计
如果无法升级sysstat版本,可直接读取内核暴露的统计文件获取队列数据:
- 采样块层累计在途IO数,自行计算实时队列深度:
# 将nvme0n1替换为实际测试用的NVMe设备名 cat /sys/block/nvme0n1/stat | awk '{print $11}'
每秒采样该字段做差值计算,即可得到对应时间窗口的平均队列深度。
- 读取硬件层真实队列状态:安装
nvme-cli工具后,可直接读取NVMe控制器寄存器,拿到最底层的硬件提交队列、完成队列填充率,该数据不受块层统计逻辑影响,准确度最高。
3. 队列能力利用率判断方法
判断数据库是否充分利用队列能力时,不要只看平均队列深度,需要关注队列深度的分位值:可使用bcc工具集的块层跟踪工具,统计一段时间内的队列深度分布:
# 统计10秒窗口内的IO队列深度分布 /usr/share/bcc/tools/biostacks -d 10
一般来说,OLTP数据库负载下,P99队列深度能达到NVMe设备标称最大队列深度的70%以上,才算充分利用了IO队列能力。消费级NVMe标称最大队列深度通常为32,企业级NVMe通常为1024及以上。
注意:不要用旧版
iostat的avgqu-sz字段判断NVMe设备的队列负载,该值在多队列栈下恒为0,会严重误导性能判断。
内容的提问来源于stack exchange,提问者Tim
相关产品推荐
相关产品推荐

