vmstat —— 一屏判断瓶颈在 CPU、内存还是 IO

运维工具手册 01-系统监控与性能 3.7 KB 原文

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. 常见坑

  1. 直接 vmstat 无参数:输出的是开机以来的平均,看起来一切正常,会误导判断。必须带间隔。
  2. 第一行不能用:即使带间隔,第一行仍是历史平均。
  3. bo 包含预读和回写,不等于应用写了这么多;精确值看 iostat 的 wkB/s。
  4. free 小是健康的:Linux 不用内存做缓存才是浪费。
  5. 容器内数值是宿主机的:/proc 未隔离,容器监控看 cgroup 的 memory.current、cpu.stat。
  6. wa 高但 iostat 的 %util 不高:可能是网络存储(NFS/Ceph)延迟,或 wa 里混了其他阻塞。
  7. r 列在老内核里含 D 状态进程,2.5.41 之后 r 只含可运行,b 单独统计阻塞。
  8. -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高=宿主机超卖
vmstat —— 一屏判断瓶颈在 CPU、内存还是 IO - 知识库 - 起航社区