vmstat —— 一屏判断瓶颈在 CPU、内存还是 IO
vmstat —— 一屏判断瓶颈在 CPU、内存还是 IO
分类:01 系统监控与性能 适用:所有 Linux(procps-ng),字段定义几十年不变,最稳的性能入门工具 一句话:不用装、输出短、一眼看出系统卡在哪个子系统。
1. 它解决什么问题
top 告诉你谁在吃 CPU,但不告诉你为什么慢。vmstat 把 CPU、内存、交换、IO、上下文切换压缩成一行,用来判断瓶颈类型,再决定去用 iostat 还是 pidstat。
2. 基本用法
vmstat # 开机以来的平均值(没意义,别用)
vmstat 1 # 每秒一行,持续输出
vmstat 1 5 # 每秒一行,共 5 行
vmstat -w 1 # 宽格式,列不挤(推荐)
vmstat -t 1 # 带时间戳
vmstat -S M 1 # 内存单位改为 MB(M/K/G)
vmstat -a 1 # active/inactive 内存替代 buff/cache
vmstat -s # 内存统计汇总
vmstat -d # 磁盘统计
vmstat -m # 内核 slab 分配
vmstat -p /dev/sda1 # 分区级 IO
第一行是开机至今的平均值,从第二行开始才是采样值。脚本里要跳过第一行。
3. 输出怎么读
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 612340 21044 1106120 0 0 12 48 920 1530 3 1 95 1 0
3.1 procs
| 列 | 含义 | 判读 |
|---|---|---|
r |
运行队列长度(可运行进程数) | 持续 > 逻辑核数 → CPU 不够 |
b |
阻塞(不可中断睡眠)进程数 | 持续 > 0 → IO 或锁等待,配合 wa 看 |
r 包含正在运行和等待 CPU 的进程。4 核机器 r 长期 8 以上,说明排队严重。
3.2 memory / swap
| 列 | 含义 | 判读 |
|---|---|---|
swpd |
已用 swap 大小 | 非 0 不一定是问题,要看 si/so |
free |
空闲物理内存 | 小很正常,Linux 会拿去缓存 |
buff |
块设备缓冲 | 元数据缓存 |
cache |
页缓存 | 文件缓存,可回收 |
si |
每秒从 swap 换入 | 持续 > 0 = 内存不足,性能灾难 |
so |
每秒换出到 swap | 同上 |
真正的内存压力信号是 si/so 持续非 0,而不是 swpd 有值。很多机器 swap 里躺着冷数据,一年不动,不影响性能。
3.3 io
| 列 | 含义 | 判读 |
|---|---|---|
bi |
每秒从块设备读入的块数(默认 1K/块) | 持续很高 → 读密集 |
bo |
每秒写出到块设备的块数 | 持续很高 → 写密集,注意 bo 含预读/回写 |
3.4 system
| 列 | 含义 | 判读 |
|---|---|---|
in |
每秒中断数 | 异常高 → 网卡小包多、硬件问题 |
cs |
每秒上下文切换数 | 与负载比异常高 → 锁竞争、线程过多 |
经验值:cs 达到几万到十几万且 CPU 不高,多半是应用线程模型有问题(线程数爆炸、频繁加锁)。
3.5 cpu
| 列 | 含义 |
|---|---|
us |
用户态 |
sy |
内核态 |
id |
空闲 |
wa |
等 IO |
st |
被 hypervisor 偷走(虚拟机) |
us + sy + id + wa + st ≈ 100。
4. 瓶颈判定矩阵
| 现象 | 结论 | 下一步 |
|---|---|---|
r 高、us 高、id 低 |
CPU 计算瓶颈 | top/pidstat -u 1 找进程 |
r 高、sy 高 |
系统调用/切换过多 | pidstat -w 1 看 cswch/s、strace -c |
b 高、wa 高、id 高 |
磁盘 IO 瓶颈 | iostat -x 1、iotop -o |
si/so 非 0、free 低 |
内存不足,已在换页 | ps aux --sort=-%mem、加内存/查泄漏 |
st 高 |
宿主机超卖 | 找云厂商,或换规格 |
in 高、cs 高、带宽不高 |
小包/中断问题 | ethtool -S、sar -n DEV、查 DDoS |
一条命令跑完判定:
vmstat -w 1 5
5. 实战场景
5.1 故障现场 30 秒取证
{
date; uptime; free -h
vmstat -w 1 10
iostat -x 1 5
ps -eo pid,pcpu,pmem,rss,stat,cmd --sort=-pcpu | head -15
} > /tmp/snap_$(date +%F_%H%M%S).txt 2>&1
事后分析或提工单都能用,比截图强。
5.2 判断"内存泄漏"还是"缓存占满"
vmstat -a 1 5
# active 持续上涨、inactive 不涨、si/so 出现 → 真泄漏
# cache 大但 active 稳定 → 正常缓存
5.3 看 slab 是否异常膨胀
vmstat -m | sort -k2 -nr | head -10
# dentry_cache / inode_cache 巨大 → 海量小文件遍历过
# kmalloc-* 持续涨 → 内核态内存泄漏,需关注驱动/文件系统
5.4 磁盘统计快速看
vmstat -d
# reads/writes 累计值,配合间隔采样看增量
vmstat -d 1 5
6. 常见坑
- 直接
vmstat无参数:输出的是开机以来的平均,看起来一切正常,会误导判断。必须带间隔。 - 第一行不能用:即使带间隔,第一行仍是历史平均。
bo包含预读和回写,不等于应用写了这么多;精确值看iostat的wkB/s。free小是健康的:Linux 不用内存做缓存才是浪费。- 容器内数值是宿主机的:
/proc未隔离,容器监控看 cgroup 的memory.current、cpu.stat。 wa高但iostat的%util不高:可能是网络存储(NFS/Ceph)延迟,或wa里混了其他阻塞。r列在老内核里含D状态进程,2.5.41 之后r只含可运行,b单独统计阻塞。-S M只改内存单位,不改变bi/bo的块单位(仍按 1K/块 或-S生效)。
7. 速查表
vmstat -w 1 5 # 最常用:宽格式每秒 5 次
vmstat -t -w 1 # 带时间戳
vmstat -a 1 # active/inactive 内存
vmstat -s # 内存总账
vmstat -d 1 # 磁盘
vmstat -m # slab
vmstat -p /dev/sda1 # 分区
# 判定:r高us高=CPU / b高wa高=IO / si so非0=内存 / st高=宿主机超卖