磁盘性能问题往往隐藏在应用层的超时和等待背后,如果只盯着CPU和内存看,很容易漏掉真正的瓶颈。Linux环境下的运维人员习惯用iostat快速查看磁盘的吞吐量、响应时间和忙碌程度,而Windows平台虽然没有原生的iostat命令,但借助子系统或内置性能计数器同样能够获得等价的指标数据。本文先梳理iostat的输出含义,再分别介绍在Windows中运行原版iostat和用原生工具采集磁盘计数器的具体方法。

iostat的核心指标:从%util到平均队列长度
iostat属于sysstat软件包,是最常用的磁盘I/O观测工具之一。不带参数执行iostat只会输出基本的CPU和磁盘汇总信息,而加上-x参数后每一块磁盘都会展示详细的扩展统计。下面的输出片段来自一台运行中的Linux服务器:
iostat -x 1 5 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 5.00 10.00 200.00 300.00 66.67 0.15 10.00 5.00 12.50 3.33 50.00 sdb 1.20 3.40 20.00 15.00 500.00 600.00 62.86 0.80 22.86 15.00 33.33 14.29 100.00
这里最值得关注的通常是%util和await两列。%util表示设备处于忙碌状态的时间百分比,它反映的是磁盘控制器在采样周期内有多长时间在处理请求。如果这一列持续接近100%,说明磁盘几乎一直在工作,很可能已经成为系统瓶颈。await是单个I/O请求从发出到完成的平均耗时,包括排队时间和实际服务时间,单位是毫秒。await越高,应用感受到的延迟就越明显。avgqu-sz是平均队列长度,它体现了有多少请求在等待被磁盘处理,数值大于1通常意味着出现了排队。
需要注意的是,%util并不等同于磁盘的真实负载饱和度。对于SSD或者带有大型缓存的RAID控制器,多个请求可以并行处理,此时即使%util达到100%,磁盘仍可能有余力接受更多请求。反过来,在虚拟化环境下,底层存储的并发能力可能被多个虚拟机共享,%util也可能出现失真。因此更可靠的做法是同时观察await、avgqu-sz和吞吐量变化趋势,不要单独依赖%util下结论。svctm在较新版本的sysstat中已经被标记为废弃,因为它的计算方式在并行I/O场景下不再准确。
在Windows中运行原版iostat:WSL与Cygwin方案
Windows 10和Windows Server 2019之后的版本可以启用WSL功能,安装一个Linux发行版,然后使用包管理器安装sysstat。WSL2使用虚拟机运行完整的Linux内核,因此可以直接执行iostat命令。首先在管理员PowerShell中启用WSL并安装Ubuntu,过程不再赘述。进入WSL后执行以下命令安装sysstat:
sudo apt update sudo apt install sysstat -y iostat -x 1 3
如果希望不进入WSL交互终端,直接在PowerShell中调用,可以使用wsl命令加参数。例如下面的命令会在默认Linux发行版中执行iostat,并输出3次采样:
wsl iostat -x 1 3
WSL中的iostat看到的磁盘设备通常是虚拟磁盘,比如/dev/sdb可能对应Windows的物理磁盘,也可能对应虚拟硬盘文件。如果要分析宿主机的物理磁盘利用率,需要确认WSL配置。WSL2默认将Windows的C:\盘挂载到/mnt/c,但它自己的根文件系统位于虚拟磁盘中。如果iostat显示的设备不是宿主机的物理磁盘,可以通过修改WSL配置文件将磁盘直通给子系统,但这在生产环境中并不常见。因此WSL方案更适合开发测试环境,用于快速查看Linux容器或应用程序的磁盘行为。
另一种方案是安装Cygwin,它是一个在Windows上提供类Unix环境的工具集。Cygwin仓库中包含sysstat包,安装完成后iostat.exe会位于C:\cygwin64\bin\目录下。可以直接在命令提示符或PowerShell中使用完整路径调用:
C:\cygwin64\bin\iostat.exe -x 1 5
不过Cygwin的iostat读取的是Cygwin模拟的设备节点,同样无法直接映射到Windows物理磁盘的计数器。以上两种方式虽然能让用户使用熟悉的iostat命令,但获取到的数据并不完全等同于Windows性能监视器中的PhysicalDisk计数器。如果要对Windows Server进行生产级监控,还是应该优先使用Windows原生的性能计数器工具。
Windows原生替代方案:typeperf与PowerShell性能计数器
Windows内置了一套完整的性能计数器体系,磁盘相关的计数器位于PhysicalDisk对象下。使用typeperf命令可以在命令行中采集这些计数器,它位于C:\Windows\System32\typeperf.exe。下面的命令每秒采样一次,共采样5次,输出磁盘总吞吐量和平均队列长度:
typeperf "\PhysicalDisk(_Total)\Disk Read Bytes/sec" "\PhysicalDisk(_Total)\Disk Write Bytes/sec" "\PhysicalDisk(_Total)\Avg. Disk Queue Length" -si 1 -sc 5
typeperf的输出格式为CSV,第一列是时间戳,后续每列对应一个计数器。需要注意的是,Disk Read Bytes/sec和Disk Write Bytes/sec的单位是字节每秒,如果希望与iostat的rkB/s和wkB/s对比,只需将数值除以1024即可。Avg. Disk Queue Length直接对应iostat中的avgqu-sz,表示当前排队的磁盘请求数量。Windows中还有一个% Disk Time计数器,它通常被解释为磁盘忙碌时间百分比,但与Linux的%util在计算方式上存在差异。在RAID或多磁盘控制器环境下,% Disk Time可能会超过100%,因此不建议直接拿它和%util进行严格对比。
更推荐的指标是% Idle Time,它表示磁盘空闲时间百分比。用100减去% Idle Time就可以得到实际的忙碌百分比,这个结果更接近iostat的%util。PowerShell的Get-Counter命令同样可以采集这些计数器,而且可以方便地格式化输出或导出数据。下面的示例获取空闲时间、队列长度以及平均读写延迟:
Get-Counter -Counter "\PhysicalDisk(_Total)\% Idle Time","\PhysicalDisk(_Total)\Avg. Disk Queue Length","\PhysicalDisk(_Total)\Avg. Disk sec/Read","\PhysicalDisk(_Total)\Avg. Disk sec/Write" -SampleInterval 1 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Format-Table -AutoSize
Avg. Disk sec/Read和Avg. Disk sec/Write的单位是秒,将它们乘以1000就得到毫秒值,可与iostat的r_await和w_await类比。比如0.015秒相当于15毫秒,说明单次读取的平均延迟较高,需要进一步排查。如果要持续监测,可以使用Export-Counter将数据保存到CSV文件,路径可以指定为C:\PerfLogs\disk_metrics.csv,便于后续导入Excel或分析工具。
实战案例:定位Windows磁盘瓶颈
假设一台文件服务器的读写响应突然变慢,CPU和内存使用率都在正常范围。我们可以在PowerShell中执行以下命令,持续采集60秒的关键磁盘计数器,并将结果保存到C:\PerfLogs\disk_metrics.csv:
$outputPath = "C:\PerfLogs\disk_metrics.csv" Get-Counter -Counter "\PhysicalDisk(_Total)\% Idle Time","\PhysicalDisk(_Total)\Avg. Disk Queue Length","\PhysicalDisk(_Total)\Avg. Disk sec/Read","\PhysicalDisk(_Total)\Avg. Disk sec/Write","\PhysicalDisk(_Total)\Disk Read Bytes/sec","\PhysicalDisk(_Total)\Disk Write Bytes/sec" -SampleInterval 2 -MaxSamples 30 | Export-Counter -Path $outputPath -FileFormat CSV
采集完成后打开CSV文件,可以看到每隔2秒一行数据。典型的磁盘瓶颈数据表现如下表所示:
| 时间 | % Idle Time | Avg. Disk Queue Length | Avg. Disk sec/Read | Avg. Disk sec/Write |
|---|---|---|---|---|
| 14:00:02 | 5.2 | 3.8 | 0.002 | 0.031 |
| 14:00:04 | 2.1 | 5.4 | 0.003 | 0.048 |
| 14:00:06 | 0.8 | 7.2 | 0.002 | 0.062 |
| 14:00:08 | 1.5 | 6.9 | 0.003 | 0.055 |
从数据中可以看到磁盘空闲时间一直接近于0,队列长度持续大于5,写入延迟高达50毫秒以上,而读取延迟相对正常。这说明磁盘写入路径存在严重拥塞,很可能是RAID写缓存失效、磁盘老化或大量并发写入导致。此时可以结合物理磁盘型号和RAID配置进一步定位,比如检查写入缓存策略,或者将部分负载迁移到SSD。
定位到瓶颈后,优化手段通常包括更换更高性能的磁盘、调整RAID级别、增大写缓存、优化应用写入模式等。但需要注意的是,Windows的磁盘计数器反映的是逻辑磁盘之上的汇总数据,如果使用存储空间直通或SAN存储,还需要在存储端查看更详细的性能指标。对于虚拟化环境,宿主机和虚拟机内部的计数器都要检查,才能判断瓶颈到底出在哪一层。
总结
Windows环境下的磁盘利用率分析并不比Linux困难,只是工具形态和指标含义略有不同。如果团队已经习惯了iostat的输出格式,通过WSL或Cygwin可以快速获得熟悉的数据视图,但它们的局限性也很明显,不适合直接用于Windows生产环境监控。对于Windows Server,typeperf和PowerShell的Get-Counter是更可靠且无需额外安装的选择,配合% Idle Time、Avg. Disk Queue Length和Avg. Disk sec/Read等计数器,足以构建出与iostat等价的性能画像。关键还是要理解每个指标背后的含义,避免将Linux的%util和Windows的% Disk Time混为一谈,同时结合队列长度和读写延迟综合判断,才能准确识别存储瓶颈并做出合理的优化决策。

