CPU 负载与 I/O 负载详解:原理、压力来源、监控与调优
在性能工程中,我们常说"CPU 密集型"用 CPU 负载衡量系统压力,"I/O 密集型"用 I/O 负载衡量系统压力。本文系统梳理这两类负载到底指什么操作、为什么会给系统带来压力、压力过大时如何解决,以及如何获取这些指标。
一、基本概念:负载(Load)到底是什么
在 Linux 中,"负载"最直观的体现是 load average(平均负载),它表示的是:在单位时间内,系统中处于可运行状态(R)和不可中断睡眠状态(D)的平均进程数。
- R(Running/Runnable):正在 CPU 上运行,或在运行队列里等待 CPU 调度的进程。→ 对应 CPU 负载
- D(Uninterruptible Sleep):正在等待磁盘 I/O 或某些内核锁,不可被信号中断的进程。→ 对应 I/O 负载
所以 load average 同时包含了 CPU 压力和 I/O 压力两类。这就是为什么单看负载高,无法判断瓶颈到底在 CPU 还是在磁盘——需要结合更多指标。
$ uptime
10:30:00 up 30 days, 2 users, load average: 2.50, 1.80, 1.20
↑1分钟 ↑5分钟 ↑15分钟
经验法则:负载值长期 > CPU 逻辑核数 × 1,说明系统存在压力;> 核数 × 2~4 通常意味着明显过载。
二、CPU 负载
2.1 CPU 负载主要指什么操作
CPU 负载高,意味着大量时间花在 CPU 计算本身,而非等待外部资源。典型操作:
| 数值计算 | 科学计算、矩阵运算、加密/解密(AES、RSA)、哈希计算(SHA、bcrypt) |
| 数据处理 | 大规模排序、聚合、正则匹配海量文本、JSON/XML 解析与序列化 |
| 编译与压缩 | 代码编译(gcc/javac)、视频转码(H.264/H.265)、压缩解压(gzip/zstd) |
| 机器学习 | 模型训练、推理(前向/反向传播)、特征工程 |
| 业务逻辑 | 复杂业务规则计算、图算法、递归回溯、虚拟机/JIT 执行 |
| 内存密集计算 | 大对象 GC(垃圾回收会占 CPU)、内存拷贝、序列化 |
特征:进程大部分时间处于 R 状态,频繁占用 CPU 时间片,几乎不阻塞在磁盘或网络上。
2.2 为什么会给系统带来压力
2.3 CPU 压力过大时如何解决
先定位再优化:
2.4 如何获取 CPU 指标
| uptime / cat /proc/loadavg | 查看平均负载 | 1/5/15 分钟 load average |
| top / htop | 进程级 CPU 占用 | %CPU、运行队列长度、us/sy/si/wa |
| vmstat 1 | 系统级 CPU 与上下文切换 | r(运行队列)、us、sy、cs(上下文切换) |
| mpstat -P ALL 1 | 每个 CPU 核的使用率 | %usr/%sys/%iowait/%idle |
| pidstat 1 | 进程级 CPU | 各进程 %CPU |
| perf top / perf record | 函数级热点剖析 | CPU 周期占用排行 |
| sar -u 1 | 历史与实时 CPU | 长期趋势 |
| ps -eLo psr,pid,comm | 查看线程跑在哪核 | 绑核分析 |
关键解读:
- us 高 → 用户态计算密集,优化业务代码。
- sy 高 → 内核态开销大,可能是系统调用/上下文切换/锁竞争过多。
- si(softirq)高 → 网络中断/软中断频繁。
- wa(iowait)高 → 实际是磁盘瓶颈"伪装"成 CPU 等待,应转向 I/O 分析。
三、I/O 负载
3.1 I/O 负载主要指什么操作
I/O 负载高,意味着大量进程阻塞在 等待外部数据传输 上(D 状态)。I/O 分为几类:
| 磁盘 I/O | 数据库读写(MySQL/PostgreSQL)、日志写入、文件上传下载、大文件读取、Checkpoint 刷盘 |
| 网络 I/O | HTTP/RPC 调用、数据库连接等待、Kafka 收发、跨机房同步、CDN 回源 |
| 终端/设备 I/O | 串口、键盘输入(现代场景少) |
| IPC I/O | 管道、共享内存、Unix Socket 传输大数据 |
特征:进程大量时间处于 D 状态,CPU 反而可能很闲(%idle 高但 load average 高),典型"CPU 没满但系统卡"。
3.2 为什么会给系统带来压力
3.3 I/O 压力过大时如何解决
磁盘 I/O 方向:
网络 I/O 方向:
3.4 如何获取 I/O 指标
| iostat -dx 1 | 每块磁盘的 I/O 统计 | r/s、w/s、rkB/s、await、%util、svctm |
| vmstat 1 | 系统级 I/O 与运行状态 | bo/bi(块读写)、wa(iowait)、b(D 状态进程数) |
| iotop | 进程级 I/O 占用 | 各进程读写带宽 |
| pidstat -d 1 | 进程级磁盘 I/O | 进程 kB_rd/s、kB_wr/s |
| dstat | 综合 | 磁盘、网络、CPU 一屏 |
| sar -d 1 / sar -n DEV 1 | 历史磁盘与网络 | 长期趋势 |
| nstat/ss -s/netstat -s | 网络协议栈 | 重传、丢包、连接数 |
| ethtool/iftop/nethogs | 网卡与进程级流量 | 带宽占用、收发速率 |
| blktrace / ftrace | 块层追踪 | I/O 落盘路径与延迟分布 |
关键解读:
- await 高 → 请求在队列里等太久,磁盘可能过载或随机 I/O 过多。
- %util 接近 100% → 磁盘带宽/时间被打满(注意:SSD 上 %util=100% 不一定到瓶颈,因多队列并发)。
- wa(iowait)高 + b 高 + CPU %idle 高 → 典型 I/O 瓶颈。
- 网络 retrans/drop 增长 → 网络质量问题。
四、CPU 负载 vs I/O 负载对比
| 进程状态 | 主要 R(运行/就绪) | 主要 D(不可中断睡眠) |
| 瓶颈位置 | CPU 算力 | 磁盘/网络/设备 |
| 典型 top 表现 | us/sy 高,%idle 低 | %idle 高,wa 高,load 高 |
| 优化方向 | 扩容、算法、异步卸载 | 缓存、批量、异步、升级存储 |
| 时间尺度 | 纳秒~毫秒 | 微秒~秒 |
| 常见误判 | 把 GC 停顿当 I/O | 把 iowait 高当 CPU 不够 |
快速判断口诀
- CPU %us 高 + load 高 → CPU 密集,去优化计算。
- CPU %idle 高 + wa 高 + load 高 → I/O 密集,去优化存储/网络。
- %sy 高 → 系统调用/上下文切换/锁竞争,去减少线程数与锁。
- load 高但 CPU/IO 都不突出 → 可能 D 状态进程多(内核锁、NFS 挂载卡死),排查内核态。
五、监控指标获取总览(命令速查)
# === 综合负载 ===
uptime # load average
cat /proc/loadavg # 负载 + 运行/总进程数
# === CPU ===
top -bn1 | head -5 # CPU 总览
mpstat -P ALL 1 2 # 每核使用率
vmstat 1 5 # r/b/cs/us/sy/wa
pidstat -u 1 # 进程 CPU
perf top # 函数热点
# === 磁盘 I/O ===
iostat -dx 1 5 # 每盘 IOPS/带宽/await/util
iotop -o # 进程 I/O
pidstat -d 1 # 进程读写
sar -d 1 # 历史磁盘
# === 网络 I/O ===
sar -n DEV 1 # 网卡流量
ss -s / netstat -s # 连接与协议栈
nethogs # 进程级流量
# === 综合可视化 ===
dstat -tcdmn # 一屏看 CPU/磁盘/网络/内存
推荐持续监控栈
- Prometheus + node_exporter + Grafana:长期存储与可视化 CPU/I/O 指标。
- node_exporter 暴露 node_load1/5/15、node_cpu_*、node_disk_*、node_network_*。
- 业务侧:APM(SkyWalking/Pinpoint)追踪慢调用,区分 CPU 瓶颈与外部 I/O 瓶颈。
六、小结
一句话:先分清"在算"还是"在等",再决定是优化 CPU 还是优化 I/O,这是所有性能调优的起点。
网硕互联帮助中心






评论前必须登录!
注册