一个经典的矛盾现场:告警说负载 20 多,登上服务器 top 一看,CPU 百分之八九十都在 idle,机器却卡得敲命令都费劲。新手会怀疑监控坏了,老手知道这是 IO 瓶颈的标志性画面。要读懂它,得先弄明白 load average 到底在数什么:Linux 的负载统计的是“可运行状态(R)+ 不可中断睡眠(D)”的任务总数。一堆进程卡在等磁盘的 D 状态,负载照样爆表,CPU 却闲得发慌。
D 状态(uninterruptible sleep)是关键角色:进程发起读写后等硬件返回,内核不让打断,连 kill -9 都杀不掉,只能等 IO 完成或者底层存储恢复。所以负载高 CPU 低的排查,方向不是找吃 CPU 的进程,而是找堵在 IO 队列里的进程和那块出问题的盘。
# 第一步:vmstat 定方向,看两列——b(阻塞进程数)和 wa(IO等待占比)
vmstat 1 5
# r b swpd free buff cache si so bi bo us sy id wa
# 1 9 0 102400 8192 512000 0 0 0 10000 3 3 75 19
# b 高 + wa 高:IO 瓶颈实锤;si/so 持续非零:内存不足在换页
# 第二步:确认 D 状态进程都是谁
ps -eo state,pid,user,comm,wchan | awk '$1 ~ /D/'
定位到“是 IO 问题”后,下钻到设备和进程两层。设备层看 iostat:重点盯 %util(设备繁忙时间占比,接近 100% 就是饱和)和 await(平均等待毫秒,机械盘正常个位数,几十上百毫秒就是盘顶不住了)。进程层用 iotop 或 pidstat 找出谁在疯狂读写——常见嫌疑人:正在跑的备份脚本、MySQL 大查询落临时表、日志疯写、还有挂死的 NFS 挂载(每个碰它的进程都进 D 状态,负载直线起飞)。
# 设备层:哪块盘饱和了
iostat -xz 1 3 # 看 %util 和 await
# 进程层:谁在打盘(-o 只显示有 IO 活动的)
iotop -boPa -n 3 | head -15
# 没装 iotop 用 pidstat 替代
pidstat -d 1 3 | sort -k5 -rn | head
# 嫌疑进程是备份/同步任务时,降 IO 优先级而不是粗暴杀掉
ionice -c3 -p <PID>
对症下药的方案按根因分四类:备份或 rsync 打满盘,用 ionice 降级并把任务挪到低峰期;内存不足导致频繁 swap(vmstat 的 si/so 持续非零),限制 FPM 子进程数、调小数据库缓冲或者加内存;慢查询把临时表写到盘上,回到慢查询治理那条线;NFS 挂载挂死,umount 掉再修存储。有一种情况要单独提:云服务器上这些指标全正常、盘也不忙,但 IO 就是慢——查一下云监控里磁盘的突发带宽或 IOPS 是不是耗尽了,云盘的性能配额也是会“顶格”的。
收尾三条纪律:一是别急着重启,重启清空全部现场,而且诱因(比如定时备份)第二天照来;二是判断负载高低要除以核数,四核机器 load 4 是刚好用满,三十二核机器 load 4 根本不叫事;三是监控告警单独给 iowait 设阈值,别只盯总负载——wa 常年超过百分之十就该去查盘了。负载高 CPU 空闲这个“矛盾”,本质就是 Linux 负载定义里藏着的另一半故事,读懂它,这类故障五分钟定性。
相关阅读:负载高但 CPU 空闲是系统层最迷惑人的现象。《服务器故障排查总纲:按现象反查的五层定位法》专门为这类“表象和病根不符”的故障做了分层,本篇是系统层的对照篇。
A5创业网 版权所有