如何利用cpustat高效追踪CPU历史数据,优化系统性能细节?
- 内容介绍
- 文章标签
- 相关推荐
在现代 Linux 程序中,CPU 的使用率往往是性能瓶颈的首要指示器。很多管理员在排查慢速响应或高负载时常常面临以下痛点:
- 无法快速定位哪些进程持续占用 CPU。
- 缺乏历史视角,导致只能看到瞬时数据而无法判断趋势。
- 手动收集日志繁琐,分析过程耗时。老实说,
幸运的是cpustat给了我们一个简洁、可脚本化的方法。下面按步骤拆解如何高效追踪 CPU 历史数据,并用这些数据来调整程序性能。话说回来,
1️⃣ 准备工作:安装 sysstat 包
cpustat 并不是单独安装的工具。它依赖于 sysstat。怎么说呢,请根据发行版执行相应命令:
Debian / Ubuntu
sudo apt-get update
sudo apt-get install sysstat
Red Hat / CentOS / Fedora
sudo yum install sysstat # RHEL/CentOS
# 或者
sudo dnf install sysstat # Fedora
安装完成后确认服务已启动:
-
Debian/Ubuntu:
sudo systemctl start sysstat -
CentOS/RHEL/Fedora:
sudo systemctl start sysstat
2️⃣ 收集历史 CPU 数据 – cpustat 的主要功能
-h / --hist: 查看最近一次采样的完整统计信息。怎么说呢,
# 查看最新采样
cpustat -h
# 等价命令
cpustat --hist
-s SECONDS DURATION: 设置采样间隔和总采样次数。从而生成自定义长度的历史记录文件。
# 每秒采样一次共采样10次
cpustat -s 1 10
# 默认情况下cpustat 会把结果保存到当前目录下的 cpu_usage.log 文件中。怎么说呢,# 如需自定义文件名,可配合 shell 重定向:
cpustat -s 1 10> ~/cpu_history.log
若想长期保留历史。可以结合 cron 定期执行上述命令,将日志归档到指定目录。
3️⃣ 分析日志文件:快速识别瓶颈所在
打开生成的 log 文件,你会看到类似以下格式:
Date: Mon Aug 21 12:00:01 UTC 2026
CPU=0 %usr=5.00 %nice=0.00 %sys=1.50 %iowait=0.20 %steal=0.00 %idle=93.30
Date这方面。Mon Aug 21 12:00:02 UTC 2026
CPU=0 %usr=7.80 %nice=0.00 %sys=1.70 %iowait=0.15 %steal=0.00 %idle=90.35
...
*痛点*: “我只想知道哪些进程导致了高 CPU,但日志里没有进程信息。” 为了解决此痛点,可将 cpustat 与 top 或 pidstat 配合使用。在同一时间段内抓取进程级别的数据,接下来做交叉比对。
a) 快速查看全局趋势
# 安装 gnuplot
sudo apt-get install gnuplot
# 将 log 转换为 gnuplot 可读格式,并绘图
awk '{print $4}' cpu_usage.log | gnuplot -e "set terminal pngcairo;set output 'cpu_trend.png';plot '-' using 1 with lines title 'CPU% Idle'"
# 上述仅示例,实际需根据字段位置调整脚本。
b) 与 pidstat 对齐:定位占用高 CPU 的进程集合
# 在同一时间段内收集 pidstat 数据:
pidstat -u -r -d -t -D ALL --interval 1 --count 10> pidstats.log
# 使用脚本将两份日志关联,例如通过时间戳匹配。# 此处略去具体实现细节,但思路是:在同一分钟内。对比 cpustat 的 usr+sys% 与 pidstat 中每个进程的 cpu%。
4️⃣ 解读关键指标:把数字转化为行动教程
| %idle | %iowait | %steal |
|---|---|---|
| 解释 %idle 高于95%: 程序空闲过多,可考虑关闭不必要服务;%idle 较低 : 持续高负载,可能需要升级硬件或调整代码;%iowait 高于5%: I/O 成为瓶颈,可检查磁盘性能、RAID 配置或数据库查询;%steal 高于10%: 虚拟化资源分配不足,考虑调整 VM 配置或物理主机资源分配。 | ||
*痛点*: “我不清楚什么时候该升级硬件还是调整软件。” 上表提供了基于指标的初步诊断框架,让你能快速决定接下来行动。
5️⃣ 基于 cpustat 输出做设置调整举例
- A/B 测试算法改造: 当发现某程序持续占用>70% 使用者态 CPU 时可先把它跑到实验环境中。用更,再回滚验证效果,
- CFS 调度调优: 如果多核程序出现频繁上下文切换,可以通过 `echo "500000" | sudo tee /proc/sys/kernel/sched_latency_ns` 调整调度阈值。
- I/O 性能提高: 针对高 iowait,可以考虑 SSD 替换、RAID‑Z 冗余、或者挂载参数 `queue_depth` 和 `noop`/`deadline` 合理配置。
- Cpufreq 控制: 使用 `cpupower frequency-set --governor performance` 保持 CPU 在最高频率运行,以应对短时峰值需求;若需节能则切回 `powersave` 并监测功耗变化。
- SMP 主要数平衡: 对于虚拟机密集型工作负载。根据 cpustat 输出可虚拟机分配给每个物理核的 vCPU 数量,避免单核过载导致整体延迟上升。
- *注*: 所有改动请先在测试环境验证。再推到生产环境,以免引入新的瓶颈。
6️⃣ 自动化与报警:让程序自己提醒你何时出问题
*痛点*: “我每天都得手工跑报告,却总是错过关键瞬间。” 可以借助监控网站或简单的 cron+邮件脚本,实现实时报警。
Promeus + Grafana 快速上手示例
- Add node_exporter 到 Promeus 抓取目标列表。
- Create Grafana dashboard 显示 `%idle`。`%iowait`,`%steal` 三条曲线。怎么说呢,
- Promeus Alertmanager 设置规则。例如:当 `%idle` 连续5分钟低于25% 时触发邮件报警。其实, " li>"在生产环境部署前。请先做好权限和安全配置,避免暴露敏感端口。" " " " " " " " " " \ \ \ bash export ALERT_EMAIL='' echo 'global: smtp_smarthost: \"smtp.example.com\" smtp_auth_username: \"\" smtp_auth_password: \"****\"'> /etc/alertmanager/config.yml
在现代 Linux 程序中,CPU 的使用率往往是性能瓶颈的首要指示器。很多管理员在排查慢速响应或高负载时常常面临以下痛点:
- 无法快速定位哪些进程持续占用 CPU。
- 缺乏历史视角,导致只能看到瞬时数据而无法判断趋势。
- 手动收集日志繁琐,分析过程耗时。老实说,
幸运的是cpustat给了我们一个简洁、可脚本化的方法。下面按步骤拆解如何高效追踪 CPU 历史数据,并用这些数据来调整程序性能。话说回来,
1️⃣ 准备工作:安装 sysstat 包
cpustat 并不是单独安装的工具。它依赖于 sysstat。怎么说呢,请根据发行版执行相应命令:
Debian / Ubuntu
sudo apt-get update
sudo apt-get install sysstat
Red Hat / CentOS / Fedora
sudo yum install sysstat # RHEL/CentOS
# 或者
sudo dnf install sysstat # Fedora
安装完成后确认服务已启动:
-
Debian/Ubuntu:
sudo systemctl start sysstat -
CentOS/RHEL/Fedora:
sudo systemctl start sysstat
2️⃣ 收集历史 CPU 数据 – cpustat 的主要功能
-h / --hist: 查看最近一次采样的完整统计信息。怎么说呢,
# 查看最新采样
cpustat -h
# 等价命令
cpustat --hist
-s SECONDS DURATION: 设置采样间隔和总采样次数。从而生成自定义长度的历史记录文件。
# 每秒采样一次共采样10次
cpustat -s 1 10
# 默认情况下cpustat 会把结果保存到当前目录下的 cpu_usage.log 文件中。怎么说呢,# 如需自定义文件名,可配合 shell 重定向:
cpustat -s 1 10> ~/cpu_history.log
若想长期保留历史。可以结合 cron 定期执行上述命令,将日志归档到指定目录。
3️⃣ 分析日志文件:快速识别瓶颈所在
打开生成的 log 文件,你会看到类似以下格式:
Date: Mon Aug 21 12:00:01 UTC 2026
CPU=0 %usr=5.00 %nice=0.00 %sys=1.50 %iowait=0.20 %steal=0.00 %idle=93.30
Date这方面。Mon Aug 21 12:00:02 UTC 2026
CPU=0 %usr=7.80 %nice=0.00 %sys=1.70 %iowait=0.15 %steal=0.00 %idle=90.35
...
*痛点*: “我只想知道哪些进程导致了高 CPU,但日志里没有进程信息。” 为了解决此痛点,可将 cpustat 与 top 或 pidstat 配合使用。在同一时间段内抓取进程级别的数据,接下来做交叉比对。
a) 快速查看全局趋势
# 安装 gnuplot
sudo apt-get install gnuplot
# 将 log 转换为 gnuplot 可读格式,并绘图
awk '{print $4}' cpu_usage.log | gnuplot -e "set terminal pngcairo;set output 'cpu_trend.png';plot '-' using 1 with lines title 'CPU% Idle'"
# 上述仅示例,实际需根据字段位置调整脚本。
b) 与 pidstat 对齐:定位占用高 CPU 的进程集合
# 在同一时间段内收集 pidstat 数据:
pidstat -u -r -d -t -D ALL --interval 1 --count 10> pidstats.log
# 使用脚本将两份日志关联,例如通过时间戳匹配。# 此处略去具体实现细节,但思路是:在同一分钟内。对比 cpustat 的 usr+sys% 与 pidstat 中每个进程的 cpu%。
4️⃣ 解读关键指标:把数字转化为行动教程
| %idle | %iowait | %steal |
|---|---|---|
| 解释 %idle 高于95%: 程序空闲过多,可考虑关闭不必要服务;%idle 较低 : 持续高负载,可能需要升级硬件或调整代码;%iowait 高于5%: I/O 成为瓶颈,可检查磁盘性能、RAID 配置或数据库查询;%steal 高于10%: 虚拟化资源分配不足,考虑调整 VM 配置或物理主机资源分配。 | ||
*痛点*: “我不清楚什么时候该升级硬件还是调整软件。” 上表提供了基于指标的初步诊断框架,让你能快速决定接下来行动。
5️⃣ 基于 cpustat 输出做设置调整举例
- A/B 测试算法改造: 当发现某程序持续占用>70% 使用者态 CPU 时可先把它跑到实验环境中。用更,再回滚验证效果,
- CFS 调度调优: 如果多核程序出现频繁上下文切换,可以通过 `echo "500000" | sudo tee /proc/sys/kernel/sched_latency_ns` 调整调度阈值。
- I/O 性能提高: 针对高 iowait,可以考虑 SSD 替换、RAID‑Z 冗余、或者挂载参数 `queue_depth` 和 `noop`/`deadline` 合理配置。
- Cpufreq 控制: 使用 `cpupower frequency-set --governor performance` 保持 CPU 在最高频率运行,以应对短时峰值需求;若需节能则切回 `powersave` 并监测功耗变化。
- SMP 主要数平衡: 对于虚拟机密集型工作负载。根据 cpustat 输出可虚拟机分配给每个物理核的 vCPU 数量,避免单核过载导致整体延迟上升。
- *注*: 所有改动请先在测试环境验证。再推到生产环境,以免引入新的瓶颈。
6️⃣ 自动化与报警:让程序自己提醒你何时出问题
*痛点*: “我每天都得手工跑报告,却总是错过关键瞬间。” 可以借助监控网站或简单的 cron+邮件脚本,实现实时报警。
Promeus + Grafana 快速上手示例
- Add node_exporter 到 Promeus 抓取目标列表。
- Create Grafana dashboard 显示 `%idle`。`%iowait`,`%steal` 三条曲线。怎么说呢,
- Promeus Alertmanager 设置规则。例如:当 `%idle` 连续5分钟低于25% 时触发邮件报警。其实, " li>"在生产环境部署前。请先做好权限和安全配置,避免暴露敏感端口。" " " " " " " " " " \ \ \ bash export ALERT_EMAIL='' echo 'global: smtp_smarthost: \"smtp.example.com\" smtp_auth_username: \"\" smtp_auth_password: \"****\"'> /etc/alertmanager/config.yml

