当你的Linux服务器响应变慢、负载飙升,但CPU和内存却相对空闲时,罪魁祸首往往隐藏在磁盘IO链路上。无论是数据库写入频繁、日志量暴增,还是某个进程在疯狂读写,磁盘IO瓶颈都会让整个系统陷入“假死”状态。要精准定位问题,iostat和iotop是运维工具箱里最直接的两件兵器。本文不讲空话,从实战角度拆解它们的使用方法和排查逻辑。
一、磁盘IO瓶颈:症状与本质
磁盘IO瓶颈的典型症状包括:系统平均负载(load average)升高、iowait(%iowait)飙高、应用程序响应延迟加大,但CPU用户态占用率并不饱和。此时磁盘成为木桶最短的那块板——线程在等待IO完成,CPU只能空转。
IO瓶颈的根本原因是请求速率超过了磁盘处理能力。机械硬盘受限于寻道时间和旋转延迟,SSD则受限于控制器或NAND闪存极限。排查的目标就是找出哪个设备、哪个进程、哪个读写类型(随机/顺序、读/写)在压垮IO子系统。
二、iostat:全局IO视图与设备级分析
2.1 安装与基本用法
iostat包含在sysstat包中,多数发行版可直接安装:
# CentOS / RHEL
yum install sysstat -y
# Ubuntu / Debian
apt install sysstat -y
最常用命令:iostat -x 1 5,每1秒输出一次扩展统计,共5次。-x参数会显示磁盘利用率、平均IO队列长度、平均服务时间等关键指标。
2.2 关键输出字段解读
以iostat -x输出为例,重点关注以下字段:
- %util:磁盘忙绿百分比。如果接近100%,说明磁盘几乎一直有IO请求在处理。但注意,对固态盘%util可能因多队列而失真,需结合其他指标。
- avgqu-sz:平均IO请求队列长度。持续大于1通常表明后端处理跟不上。
- await:平均每次IO请求的等待时间(包括队列等待和服务时间)。单位为毫秒。机械盘await超过30ms即需要警惕,SSD超过5ms可能异常。
- svctm:平均服务时间(已废弃,但仍可见)。更可靠的是await与svctm的差值,反映队列延迟。
- r/s 和 w/s:每秒读/写请求数。
- rkB/s 和 wkB/s:每秒读写数据量。
实战经验:当%util高但r/s和w/s并不高时,往往是大块顺序IO(如备份、日志)或磁盘存在硬件问题。当%util不高但await很高时,可能是IO被上层的文件系统或缓存队列阻塞,或者磁盘降速。
2.3 场景案例:定位磁盘负载不均
假设一台数据库服务器响应变慢,执行iostat -x 1 3,发现sda的%util为98%,await达120ms,而sdb几乎空闲。这就明确了瓶颈盘是sda。接下来应检查sda上的分区挂载点(mount | grep sda),通常是数据盘或日志盘。此时可以缩小范围:检查该分区上哪个应用在密集IO。
三、iotop:进程级IO占用精准定位
3.1 安装与基础操作
iotop基于内核的IO统计接口,需要root或sudo权限:
# 安装
yum install iotop -y # 或 apt install iotop -y
# 运行
sudo iotop -oP
参数说明:-o(only)只显示实际有IO操作的进程,-P显示进程而不是线程,避免杂乱输出。
3.2 看懂iotop输出
iotop实时显示每个进程的:
- DISK READ 和 DISK WRITE:当前读写速率。
- IO:I/O优先级。
- 进程名、PID等。
关键技巧:直接按r键切换读写排序,按o切换是否只显示活动进程。当发现某个进程(如mysqld或java)写速率达到数百MB/s时,基本锁定问题进程。
3.3 实战案例:揪出日志写爆磁盘的罪魁祸首
某应用服务器负载高,iostat看到sda的wkB/s持续300MB/s,%util接近100%。执行sudo iotop -oP,发现rsyslogd写速率异常。进一步检查日志目录/var/log,发现某个应用重复打印大量错误日志,导致syslog疯狂写入。停用该应用日志级别后,磁盘IO恢复正常。iotop在此场景中直接展示了进程级IO占用,无需猜测。
四、联合排查套路:先全局后局部
4.1 四步排查法
- 看整体:
sar -d 1 3或iostat -x 1 3,确定磁盘是否繁忙,哪块盘是热点。 - 看进程:
iotop -oP列出IO活跃的进程,识别大胃王。 - 看文件:对可疑进程,使用
lsof -p PID查看其打开的文件,或strace -e trace=file -p PID跟踪文件操作(谨慎在生产环境使用)。 - 看系统:用
dmesg检查是否有磁盘错误,用blockdev --getra /dev/sda检查磁盘预读参数。
4.2 组合命令示例
实时监控脚本:iostat -x 1 2 | awk '/^sd/ {print $1,$14}' 快速获取磁盘%util。再配合iotop -b -n 1 -oP | head -5获取一次快照。也可使用dstat -d -D sda 1 5作为补充。
五、常见误区与调优方向
5.1 误区:%util 100%一定需要换硬件?
未必。%util高可能因为IO调度器效率低、文件系统配置不当或应用程序产生了大量随机小IO。可以先尝试调整IO调度器(如从CFQ改为noop或deadline),或合并小IO请求(如数据库调整刷盘策略)。
5.2 误区:iotop看到的读写速率比iostat小?
正常现象。iostat统计的是块设备层的请求,而iotop统计的是进程经过VFS层发出的IO,再加上页缓存回写、预读等都会产生差值。应以iostat的设备层数据为准,iotop作为进程级线索。
5.3 调优方向参考
- 调整预读:
blockdev --setra 4096 /dev/sda某些场景下提升顺序读性能。 - 文件系统优化:挂载参数添加
noatime,nodiratime,避免访问时间更新。 - 应用程序侧:启用缓冲写入、合并IO、异步IO(如libaio)。
六、总结
iostat和iotop是Linux磁盘IO排查的“听诊器”和“X光机”。iostat给出全局透视——哪块盘在忙、忙的程度、延迟数据;iotop深入进程级别——谁在疯狂读写、读写模式如何。两者配合,可以快速从“系统慢”到“磁盘慢”再到“进程A慢”的三层递进式定位。记住:排查永远遵循先整体、后局部、再细节的顺序,不盲目臆断。掌握了这些实战命令,下一次磁盘IO瓶颈来临时,你就能沉着应对,让系统重新飞起来。
延伸阅读
