news 2026/9/17 7:46:01

Linux磁盘性能排查利器:iostat命令详解与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux磁盘性能排查利器:iostat命令详解与实战

iostat这个命令,我在日常运维里用的频率非常高。不管你是刚接手服务器的新人,还是处理过多次性能故障的老手,只要和 Linux 服务器打交道,磁盘 I/O 就是绕不开的一环。而 iostat 恰恰是查看磁盘读写状态最直接的工具之一。尤其是当应用响应变慢、数据库压测上不去、文件服务卡顿的时候,我第一反应往往不是去看 CPU 或内存,而是先跑几条 iostat 命令,快速确认磁盘是不是瓶颈。这篇内容我把 iostat 的安装、输出字段、常见误区、实战排查思路和监控技巧一次讲清楚,尽量用我平时实际操作中的“人话”来描述,帮你少踩点坑。

iostat 属于 sysstat 软件包,它的核心功能是监控系统输入输出设备(主要是磁盘)的负载情况。它能告诉你磁盘当前每秒读写了多少数据、每秒处理了多少次 I/O 请求、平均每次请求耗时多久、设备使用率达到了多少。这些数据合在一起,基本就能判断出一块磁盘是“在正常工作”还是“已经满负荷运转”。这篇文章适合所有需要维护 Linux 服务器的人,也适合刚学习系统监控的同学参考。我会结合自己排查过的真实场景,把安装方法、字段含义、常见坑和高级用法都展开说一下。

1. 先搞清楚 iostat 能做什么,再看怎么装

1.1 一个真实的排查场景

大概半年前,我们有一套线上应用经常在高峰期出现“卡住”的情况。登录服务器看 CPU 使用率并不高,内存也充足,但接口响应时间就是做不到原先的水平。当时我走了不少弯路,查了应用日志、看了慢查询、检查了网络,最后才想到用 iostat 看一下磁盘。结果发现一块云数据盘的%util长期在 90% 以上,await也高得离谱,问题立刻就明确了:磁盘 I/O 已经接近饱和,应用里的每一次文件读写都在排队。后来通过扩容磁盘和调整读写策略才彻底解决。

这个场景其实很有代表性。CPU、内存、磁盘、网络四大件里,磁盘 I/O 问题往往最隐蔽,因为它不像 CPU 那样有一个明显的“高占用”指标,很多时候应用的表现只是“慢”或者“偶尔卡住”。iostat 的价值就在于,它能把磁盘层的真实压力量化出来,让你不用靠猜。

1.2 一条命令能拿到哪些关键数据

iostat 从内核获取数据,然后以列表形式展示。主要有两大块内容:

  • CPU 层面的统计:%user%system%iowait%idle等。这里重点看%iowait,它代表 CPU 等待磁盘 I/O 完成的时间占比。如果这个数值持续偏高,说明 CPU 闲着等磁盘,磁盘大概率是短板。

  • 设备层面的统计:包括tps(每秒传输次数)、kB_read/skB_wrtn/sawait(平均每次 I/O 请求的处理时间)、%util(设备忙碌百分比)等。这一块是分析磁盘性能的核心,能直接看出吞吐量、响应延迟和使用率。

这些指标合在一起,基本能回答三个问题:磁盘忙不忙?有多忙?请求响应快不快?

1.3 哪些人应该重点掌握 iostat

数据库管理员(DBA)需要关注数据库数据文件所在磁盘的压力;后端开发在排查接口延迟时,需要排除磁盘因素;运维工程师做服务器巡检和故障定位时,iostat 基本是标准动作;做性能测试的同学更需要用它观察压测过程中磁盘是否成为瓶颈。可以说,只要你的应用涉及文件存储、数据库读写或日志输出,iostat 就值得你花半小时掌握。

2. iostat 安装:不同系统对应不同方法

2.1 RHEL/CentOS 系列安装

在 CentOS、Rocky Linux、AlmaLinux 这类系统上,iostat 属于 sysstat 包,直接通过 yum/dnf 安装即可:

yum install -y sysstat

如果你的系统是较新的 RHEL 9 或 Rocky Linux 9,可能需要用 dnf 命令,但包名是一样的。安装完成后,可以用rpm -ql sysstat | grep iostat确认可执行文件路径。通常是在/usr/bin/iostat下。

有一个需要注意的点:yum install sysstat会同时安装sarpidstatmpstat等命令,这是一整套 sysstat 工具。如果你只需要 iostat,目前没有更轻量的独立安装方式,接受整套即可。不过这也算好事,后面做性能分析时sarpidstat能派上大用场。

2.2 Debian/Ubuntu 系列安装

Debian、Ubuntu 系统使用 apt 安装:

apt update apt install -y sysstat

Ubuntu 上安装 sysstat 后有个细节:默认情况下 sysstat 的定时收集服务是关闭的,配置文件在/etc/default/sysstat,里面有一行ENABLED="false"。如果你后面想用sar的历史数据,需要改成ENABLED="true"再重启服务。不过 iostat 本身是即时读取内核数据的,不依赖这个开关,所以仅用 iostat 的话可以不改动它。

2.3 源码编译安装的方法

如果你的生产环境比较特殊,比如是内网离线环境,无法用 yum/apt 安装,那就需要先下载 sysstat 源码包,然后编译安装。这里分享一个我常用的离线安装思路:

  • 准备 RPM 包或 DEB 包,拷到目标机器上用rpm -ivhdpkg -i安装。这种方式最简单,但需要找到匹配系统版本的包。
  • 如果找不到现成包,可以用源码编译。步骤大致是:
wget http://pagesperso-orange.fr/sebastien.godard/sysstat-12.7.4.tar.gz tar -zxvf sysstat-12.7.4.tar.gz cd sysstat-12.7.4 ./configure make make install

这里要提醒一句:源码编译默认安装路径通常是/usr/local/bin,而不是/usr/bin。编译完成后执行which iostat查看路径,如果找不到,需要把路径加入 PATH,或者用/usr/local/bin/iostat直接调用。另外,编译过程依赖 gcc、make 等基础工具,离线环境最好提前确认这些工具已存在。

2.4 验证是否安装成功

安装完成后,执行iostat -Viostat -v查看版本号,能打印版本就说明安装成功。第一次执行iostat时,你可能会发现显示的数值看起来很大,或者某些字段跟网上教程不一样,这些都是正常现象。因为 iostat 第一次执行显示的是从系统开机到现在的平均数据,而不是“当前瞬间”的数据。想要看实时的、准确的负载情况,必须带时间间隔参数,比如iostat -x 1 3。这是很多新手容易踩的第一个坑。

3. 输出字段逐个拆解:看懂 iostat 怎么“说话”

3.1 最基础的执行方式

直接执行iostat,系统会打印从开机到当前的平均统计信息。如下是一个典型输出:

avg-cpu: %user %nice %system %iowait %steal %idle 2.55 0.00 0.85 0.23 0.00 96.37 Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn vda 8.12 251.36 98.75 10847332 4261378

这里Device是设备名称,tps是每秒 I/O 传输次数,kB_read/skB_wrtn/s是每秒读写数据量,kB_readkB_wrtn是从开机到现在的累计读写量。此输出相当于一个“总账”,排查问题时价值不大,因为它是所有时刻的平均值,会把峰值掩盖掉。

3.2 我常用的几个参数组合

排查问题我一般不会只跑裸 iostat,而是带上参数组合,最常用的几组如下:

iostat -x 1 3

这个命令的意思是:每 1 秒刷新一次,连续输出 3 次,同时使用-x参数显示扩展统计信息。-x参数会额外显示rrqm/swrqm/sr_awaitw_awaitaqu-sz%util等字段,这些才是定位磁盘性能问题的关键信息。

iostat -d 1 5

只显示设备使用状态,不显示 CPU 状态。适合脚本里定期抓取设备负载。

iostat -k -x 2 2

-k表示以 KB 为单位显示读写速度。默认 iostat 输出的单位是 KB,但在某些新版本里默认可能是 KB 或 MB,最好用-k-m强制指定。-m表示以 MB 为单位。

iostat -x -t 1 5

-t参数会在每行输出前显示当前时间。做问题记录和回溯时特别有用,能让我知道某次高负载具体发生在哪个时间点。

3.3 扩展模式下每个字段的含义

执行iostat -x 1 1后,设备部分的字段会多出很多,看起来可能有点吓人,但每一个字段背后都有实际意义:

字段含义判断要点
rrqm/s每秒合并读请求数值高说明有大量相邻的读请求被合并,不一定是坏事
wrqm/s每秒合并写请求数文件系统合并写请求可减少磁盘寻道,对机械盘有正向作用
r/s每秒实际读请求次数看随机读压力的核心指标
w/s每秒实际写请求次数看随机写压力的核心指标
rkB/s每秒读取数据量(KB)与 r/s 结合可判断单次读大小
wkB/s每秒写入数据量(KB)与 w/s 结合可判断单次写大小
avgrq-sz平均每次 I/O 的数据大小(扇区)值偏小说明以小尺寸随机 I/O 为主,通常对磁盘更不友好
avgqu-sz平均 I/O 队列长度持续大于磁盘队列深度可能意味着磁盘饱和
await平均每次 I/O 请求从提交到完成的时间(毫秒)包含排队时间和实际处理时间,用户体感最直接
r_await读请求平均等待时间(毫秒)专门看读延迟
w_await写请求平均等待时间(毫秒)专门看写延迟
svctm平均每次设备 I/O 操作的服务时间(毫秒)老版本指标,接近磁盘本身处理能力,但新内核已经弱化
%util设备忙碌时间占比设备饱和度参考指标,但需要结合队列深度理解

这里面最容易引起误解的是svctm。在新版本 iostat 里,svctm可能显示为 0 或者被移除,原因是现代块设备有复杂的缓存和多队列调度机制,单纯用“设备服务时间”描述已经不够准确。很多人还在用老思路看待 svctm,这是需要更新的知识点。

3.4 CPU 部分的快速判断

avg-cpu部分里值得重点关注的是%iowait。它表示 CPU 等待磁盘 I/O 所花时间占整个时间周期的百分比。如果%iowait持续高于 10%,就要注意磁盘是不是有点吃力了。不过这也不是绝对的——%iowait高只能说明 CPU 在等待 I/O 完成,不能直接等价于磁盘 100% 繁忙。例如一个有大量并发写操作的系统,即使磁盘已经忙不过来,%iowait也可能并不高,因为大量线程可能被阻塞在 D 状态(不可中断睡眠),而不是被统计到%iowait中。

所以我的习惯是:先看%iowait判断是否有 I/O 等待问题,再看设备级指标做精确确认,两者结合而不是只看一个项。

4. 核心指标误区与磁盘性能评估思路

4.1 %util 不是越低越好也不是越高越坏

%util代表统计周期内有百分之多少的时间设备是忙碌的。比如 70% 意味着在统计周期内,设备有 70% 的时间在处理请求,30% 的时间是空闲的。直观理解确实如此,但需要特别注意:%util只是“设备忙的时间百分比”,并不反映队列里等待了多少请求。

在老式机械硬盘时代,一块磁盘同时只能处理一个 I/O,%util 接近 100% 基本就说明到极限了。但现代设备比如 NVMe SSD、云硬盘、硬件 RAID 卡,通常支持多队列并行,可以同时处理多个 I/O 请求。所以%util达到 100% 并不一定代表磁盘没有余量。反过来,%util只有 30%,也可能因为某几个大请求卡住了应用。

看磁盘是否成为瓶颈,我更建议结合avgqu-szawait%util三个值一起来判断。如果%util高、await高、avgqu-sz同时在持续增大,那就是典型的“设备已经处理不过来了”;如果%util高但await很低,说明设备并发处理能力强,虽然忙碌但响应速度依然很快,可能还没到极限。

4.2 为什么你会看到 %util 超过 100%

我见过很多朋友在跑iostat -x时看到%util超过 100%,比如 152% 甚至 200%,然后以为工具出 bug 了。其实不是 bug。在多磁盘组成的 MD 设备、硬件 RAID 阵列、云盘这类支持并发请求的设备上,%util的计算方式会导致它可能超过 100%。它表示的是请求占用了多少“设备的服务时间”,对于有并行能力的设备来说,某一秒内可能同时有 1.5 条请求在被处理,于是数值超过 100。

所以在实践里,看到%util超过 100%,我不建议直接断定磁盘“完蛋了”,而是要去查avgqu-szawait。如果await也在同步飙升,说明并发请求真的太多、排队严重;如果await很低,那就说明设备的并行处理能力还在,可以继续观察。

4.3 随机 I/O 和顺序 I/O 对指标的影响

同样一块磁盘,跑顺序读写和随机读写,iostat 显示的指标会有天壤之别。顺序读写时磁盘寻道时间少,await可以很低,rkB/swkB/s可以很高;随机读写时则相反,大量时间耗在寻道和旋转延迟上,await会明显上升,吞吐量反而下降。

有一次我帮同事看一台机械盘服务器,await一直在 80ms 左右,他以为是磁盘快到寿命了。我让他跑了iostat -x 1观察,发现r/s很高但rkB/s很低,也就是说大量小尺寸随机读,这正好解释了高延迟。这种性能问题不是磁盘坏,而是应用访问模式导致。后面通过调整数据库缓存命中率,把很多重复读取都挡在内存层面,await迅速降了下来。

4.4 估算磁盘最大吞吐能力的简单方法

做性能基线时,可以通过对比观测值来评估还有多少余量。例如一块云上标注 350MB/s 的 SSD,线上正常业务读写总和在 120MB/s 左右,那么剩下的空间还很大。但如果你拿到一块标称 350MB/s 的盘,实际业务跑出来的写入速度只有 50MB/s,且%util已到 90% 以上,这就说明实际能用的吞吐远低于标配,就要警惕云服务商给的是否是共享型资源。为验证真实能力,我通常会在业务低峰期用fio做一轮基准测试,把峰值写吞吐测出来,再和 iostat 里的实际业务峰值对比,这样就能清楚知道磁盘余量到底如何。

5. 实战案例:一次数据库慢查询引发的磁盘排查

5.1 现象描述

有一回,一个内部系统的 MySQL 实例突然出现大量慢查询。开发那边看 SQL 并没有新增或变更,索引也都正常,于是怀疑是数据库参数问题。我登录服务器后,第一件事就是执行:

iostat -x 1 10

连续采集 10 秒数据后,很快就发现了异常:数据盘 vdb 的w/s一直在 500 到 800 之间波动,wkB/s大概在 20000KB 到 40000KB 之间,avgqu-sz持续接近 15,w_await达到 50ms 以上,%util在 85% 到 100% 之间。这个现象已经比较明确:这台实例的磁盘写入压力非常大,I/O 请求在排队,磁盘成为瓶颈。

5.2 排查过程

进一步排查时,我分了几步:

  • mysqladmin processlist看数据库当前连接和线程状态,发现不少线程处于Writing to netUpdating状态。
  • iostat -x 1 5 | grep vdb持续观察,确认高写入并非偶发尖峰,而是持续性的。
  • 检查 binlog 和事务日志,发现开启了大事务批量更新操作,并且 binlog 写入策略为同步模式。
  • 查看慢查询日志,定位到某几张表存在频繁的UPDATE操作,单次更新涉及大量行数据。

综合这些信息,我判断并非数据库参数异常,而是磁盘层写能力跟不上业务写入需求。那台实例用的是普通高效云盘,本身随机写入能力有限,在高峰期出现排队是必然结果。

5.3 解决方案和经验总结

处理方案是临时的和长期的结合:

  • 临时将 binlog 写入策略进行了适当调整,并在业务侧对大事务做了拆分,降低瞬时写入压力。
  • 长期上,联系云平台对数据盘进行扩容和升级,换到更高 I/O 能力的 SSD 类型,同时在应用层做了缓存优化,减少高频更新带来的写放大。

这个案例让我形成了一个固定习惯:遇到“应用变慢但 CPU 不高”的问题,一定先跑iostat -x 1 5。如果磁盘的await高、%util高、avgqu-sz高,那问题大概率在 I/O 层,而不是业务代码。

6. 进阶玩法:把 iostat 用成持续监控工具

6.1 周期性输出,观察峰值规律

单次执行 iostat 只能看到瞬间状态,想要评估系统整体健康,必须周期性采集。我最常用的命令是:

iostat -x -t 1 60 > /tmp/iostat_$(date +%Y%m%d_%H%M%S).log &

这会在后台记录一分钟内每秒钟的磁盘状态。等业务流程出现卡顿后,再打开日志查看当时的具体负载。这种方式的优点是零依赖、不侵入系统,也不影响业务;缺点是没有阈值告警能力,需要人工事后分析。

6.2 用脚本采集关键指标并落库

如果你管理几十台服务器,人工翻日志就不现实了。我写过一个简单的 shell 脚本,定期抓取关键指标,输出为 CSV 格式,方便后续用 Excel 或 Grafana 分析。核心思路如下:

#!/bin/bash DISK=vdb INTERVAL=10 while true; do TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S) DATA=$(iostat -x -k 1 1 | grep "$DISK" | tail -1) TS=$(echo "$DATA" | awk '{print $2}') KS=$(echo "$DATA" | awk '{print $3}') WA=$(echo "$DATA" | awk '{print $6}') UTIL=$(echo "$DATA" | awk '{print $12}') echo "$TIMESTAMP,$TS,$KS,$WA,$UTIL" >> disk_monitor.csv sleep $INTERVAL done

这里我用 awk 从 iostat 输出里抽出tpsrkB/sw_await%util等字段。需要注意的是不同版本的 iostat 输出列顺序可能有差异,脚本里硬编码列号前最好先手动跑一次确认字段位置。最保险的办法是使用关键字匹配,比如用awk输出整行,然后把字段名和值列成 JSON,再解析到监控平台。

6.3 和 vmstat、sar、pidstat 联动

iostat 很强大,但它只解决“磁盘层”的问题。想要完整定位一次性能故障,我通常会同时开三个终端分别执行:

vmstat 1 60 iostat -x 1 60 pidstat -d 1 60
  • vmstat用来观察内存、CPU 和系统级 I/O 等待。
  • iostat用来观察磁盘设备层。
  • pidstat -d用来定位到底是哪个进程在疯狂读写磁盘。

这三者一组合,就能回答三个连续问题:系统有没有 I/O 问题?哪块磁盘出问题?是哪个进程导致的?比如有一次我发现某块盘%util很高,但数据库并不在这块盘上,接着用pidstat -d才发现是日志清理程序和备份脚本同时跑,把磁盘带宽抢光了。

6.4 建立磁盘性能基线的建议

监控的最大价值不仅是“故障时发现问题”,而是“在故障发生前就识别风险”。我会在每台新服务器上线后,先在正常业务负载下运行两到三天的 iostat 采集,记录下常用的峰值和均值。例如某台机器正常业务下await通常小于 5ms,%util不超过 20%。如果某一天%util突然持续到 80%,即使业务用户还没感受到明显卡顿,我也能提前准备扩容或优化方案。这个“基线思维”比任何高级技巧都重要。

7. 常见问题与排查技巧实录

7.1 iostat 常见问题速查表

下面这些问题都是实际环境中反复出现过的,我整理成一个速查表,方便你在遇到时快速对照。

问题现象可能原因解决方法
提示command not foundsysstat 包未安装按系统安装 sysstat,或源码编译
只有 CPU 数据,没有设备数据权限不足或没有块设备使用 root 执行,或检查容器内是否映射了磁盘
%util超过 100%设备支持并发,多请求并行处理结合avgqu-szawait综合判断,不要直接判死
svctm为 0新版本移除了该字段或设备不适用改用awaitr_awaitw_await判断响应延迟
首次执行数值很大显示的是开机以来的平均值必须加时间间隔参数,如iostat -x 1 5
Docker 容器内看不到真实磁盘容器内看到的设备是宿主机共享的在宿主机上执行 iostat,或用 cgroup 层面的 io 统计
云盘延迟高但本机无异常网络存储受宿主机邻居影响多用几轮数据对比,结合云平台监控确认
输出单位不一致不同版本默认单位不同-k-m强制单位

7.2 容器环境下 iostat 的局限性

现在很多应用跑在 Docker 或 Kubernetes 里,如果在容器里执行 iostat,大概率看到的是宿主机层面的块设备信息,而不是容器自身的 I/O 限制。容器里看到的同一个设备名,实际反映的是宿主机整块磁盘的负载,无法精确对应到当前容器。

如果要做容器粒度的 I/O 监控,更可靠的方案是读取/sys/fs/cgroup/blkio下的统计文件,或者直接使用docker stats查看块 I/O 总量。不过这不代表 iostat 在容器环境没用——你仍然可以在宿主机上用它判断磁盘整体是否健康,再把容器部署调度到健康节点上。

7.3 几个我个人的实操心得

第一,iostat 的采样间隔建议选 1 秒,采样次数不要太多。iostat -x 1 3是我排查问题时最常用的组合,既能抓住实时变化,又不会因为刷屏影响操作。

第二,注意区分kB_read/s和实际业务请求。高吞吐不等于高延迟,关键是看await。有时候rkB/s已经 50MB/s,但await只有 0.5ms,说明设备响应很好,反而不用担心。

第三,不同磁盘类型有完全不同的正常基准。机械盘await在 10-20ms 以内算正常,云 SSD 通常在 1-5ms,NVMe 则可能 0.1ms 左右。建议在排查前先了解当前环境磁盘的预期性能,否则很容易产生“误报警”。

第四,iostat 输出里Device列可能是dm-0vdasda或者nvme0n1等不同名字。当服务器有多个磁盘时,先通过lsblk查看设备和挂载点对应关系,避免盯错目标。

7.4 两条能减少误判的具体技巧

一条是不要只取第一次输出作为判断依据。iostat 第一次数据表示系统启动以来的均值,必须等第二次、第三次数据出来后才反映真实负载。类似地,如果只看一两秒,很容易被瞬间尖峰误导,采样建议至少 5 秒以上再下结论。

另一条是结合错误日志一起判断。iostat 显示的高延迟可能来自磁盘坏道导致的反复重试,此时系统日志/var/log/messagesdmesg里通常会有I/O error字样。有一次我发现某块盘await高得离谱,排查时系统日志提示磁盘存在坏块,才意识到不是负载问题,而是物理硬件问题。光看 iostat 不结合系统日志,很容易漏掉这种特殊情况。

我在实际运维中有一个很深的体会:iostat 这类工具,真正用好的关键不在于背下所有参数,而是看懂指标背后的因果关系。%util高不一定是磁盘坏,await高也不一定代表磁盘在满负荷运转;判断一次 I/O 问题,一定要把设备层、进程层、访问模式结合起来看。尤其是碰到数据库等对延迟敏感的业务,提前建立好 iostat 监控基线和自动采集脚本,比每次故障时临时跑命令要有效得多。如果你刚接触 iostat,建议先把iostat -x 1 5的输出逐字段研究透,再对照实际业务验证,很快就能建立自己的判断体系。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 7:44:56

用Python开发X-Plane插件:SDK解析与嵌入式桥接实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 7:44:27

电子元器件测量基础与数字万用表使用技巧

1. 实验项目概述"电子测试平台与工具1_实验3元器件及测量基础测试B"是电子工程类专业的基础实验课程,主要面向电子测量技术初学者。这个实验的核心目标是让学生掌握常用电子元器件的识别、参数测量方法以及基础测量仪器的规范操作。在电子系统设计与调试过…

作者头像 李华
网站建设 2026/9/17 7:42:26

DeskcommCRM实战解析:从核心表结构到销售流程重塑

DeskcommCRM这名字放在桌面上第一眼,很多人会琢磨它到底是干什么的。拆开看就很直白:Desk是桌面端,Comm是通信或者说沟通记录,CRM则是客户关系管理。合在一起,就是一套以桌面端为主阵地、把沟通和客户管理揉在一起的轻…

作者头像 李华