1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com
  1. Linux 性能调优系列(一) 建立科学的性能分析思路
  2. Linux 性能调优系列(二) 掌握基础性能监控命令
  3. Linux 性能调优系列(三) sysstat实现性能数据持久采集
  4. Linux 性能调优系列(四) 别只会用 sysstat,PCP 才是 Linux 性能监控的进阶玩法
  5. Linux 性能调优系列(五) 给你的服务器做一次全面体检
  6. Linux 性能调优系列(六) 想调内核参数?先搞懂 /proc、sysctl 和 sysfs
  7. Linux 性能调优系列(七) 还在手动改 sysctl?TuneD 智能性能调优实战来了
  8. Linux 性能调优系列(八) 进程太能吃资源怎么办?用 ulimit 和 systemd 给它加个"上限"
  9. Linux 性能调优系列(九) cgroup v2实战:防止一个烂进程干崩整台服务器
  10. Linux 性能调优系列(十) CPU 100% 到底是谁在忙?用 perf 把"元凶"揪出来
  11. Linux 性能调优系列(十一) 程序为什么卡住了?strace 和 ltrace 带你找到答案
  12. Linux 性能调优系列(十二) 服务器又卡了?SystemTap 带你杀到内核看看为啥
  13. Linux 性能调优系列(十三) 从 SystemTap 到 eBPF,Linux 性能追踪进入新时代
  14. Linux 性能调优系列(十四) CPU 这么忙,到底是谁决定“让谁先跑”?一文搞懂 Linux 调度器
  15. Linux 性能调优系列(十五) CPU 到底该先给谁?搞懂 Linux 实时调度
  16. Linux 性能调优系列(十六) Linux CPU 隔离实战,为什么实时线程绑核后延迟还会抖?
  17. Linux 性能调优系列(十七) CPU 占用不高却跑的慢?深挖 CPU 缓存性能瓶颈
  18. Linux 性能调优系列(十八) 程序申请了1GB内存,为什么系统却说它没用?
  19. Linux 性能调优系列(十九) 服务器硬盘慢得像蜗牛?先别急着换硬盘,这四招先把瓶颈找出来
  20. Linux 性能调优系列(二十) 磁盘 I/O 调度器怎么选?一文搞懂 mq-deadline、kyber、bfq 和 none
  21. Linux 性能调优系列(二十一) 磁盘为什么慢?从文件系统到 I/O 调优,一次讲透
  22. Linux 性能调优系列(二十二) Linux 网络调优别乱改 sysctl!先找瓶颈再调 TCP 缓冲区
  23. Linux 性能调优系列(二十三) MTU 从 1500 到 9000,巨帧真的能提升性能吗?
  24. Linux 性能调优系列(二十四) 从 CPU 省电到网卡卸载,聊聊 Linux 网络调优
  25. Linux 性能调优系列(二十五) 聊聊VirtIO、TuneD、virtio-mem 调优

回顾上一篇,我们学了 ps、top、free、vmstat 这些系统自带命令。但是它们有一个致命短板:只能看此时此刻的状态。线上经常遇到这种糟心事:业务突然卡顿,等你登录服务器敲完命令,故障已经消失了。问题现象没了,指标也看不到,完全不知道刚才发生了什么。想要解决这个问题,我们就需要工具能够定时采集、保存历史性能数据,方便事后翻旧账排查。

sysstat 是 RHEL、Rocky、AlmaLinux 里非常经典的工具套件。它同样读取内核里面的计数器,不光能实时打印指标,还可以定时把数据写到磁盘保存下来。后面线上出问题,我们可以把几天前的性能数据调出来复盘。

sysstat包含下面这几个高频工具:

工具作用
mpstat看CPU统计,可以看整机,也可以看每一个CPU核心
iostat重点看磁盘IO,同时附带CPU信息,排查磁盘慢必用
pidstat盯单个进程,看某个进程的CPU、磁盘IO开销
sar全能大管家:实时看数据、存日志、读取历史日志,什么指标都能抓
tapestat磁带机设备统计,普通服务器几乎用不到
cifsiostatCIFS网络共享盘统计

RHEL系列默认不一定预装,先安装:

1
2
3
4
5
6
7
[root@localhost ~]# dnf install sysstat -y
...
Installed:
avahi-libs-0.9~rc2-2.el10_0.x86_64 libuv-1:1.52.1-1.el10_2.x86_64 lm_sensors-libs-3.6.0-20.el10.x86_64
pcp-conf-7.0.3-5.el10_2.x86_64 pcp-libs-7.0.3-5.el10_2.x86_64 sysstat-12.7.6-4.el10.x86_64

Complete!

sysstat几个实用优点:

  1. 可以自定义历史日志保留多少天;
  2. 支持导出 CSV / JSON / XML,方便脚本二次处理;
  3. 支持热插拔磁盘设备,新增硬盘不需要改配置;
  4. 几乎全部命令通用一套传参格式:命令 采样间隔秒数 采集多少次。

举个通用例子:iostat 1 3,意思是每1秒输出一次,一共输出3次就退出。
⚠️划重点:所有sysstat工具输出的第一行数据,是服务器开机到现在的平均值,不是实时数据!看实时请跳过第一行。

iostat:排查磁盘IO瓶颈的利器

很多业务卡顿,CPU、内存看着没事,实际上是磁盘IO打满了,这时候就要上 iostat。

最简单直接运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@localhost ~]# iostat 1 3
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0.14 0.00 0.74 0.11 0.00 99.00

Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 20.12 438.48 193.09 0.00 176755 77835 0
dm-1 0.25 5.53 0.00 0.00 2228 0 0
nvme0n1 20.36 471.27 198.17 0.00 189975 79883 0


avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 0.00 0.00 100.00

Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 0.00 0.00 0.00 0.00 0 0 0
dm-1 0.00 0.00 0.00 0.00 0 0 0
nvme0n1 0.00 0.00 0.00 0.00 0 0 0


avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.50 0.00 0.00 99.50

Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 0.00 0.00 0.00 0.00 0 0 0
dm-1 0.00 0.00 0.00 0.00 0 0 0
nvme0n1 0.00 0.00 0.00 0.00 0 0 0

常用参数组合:

  • -c:只看CPU数据,不看磁盘
  • -d:只看磁盘IO,屏蔽CPU输出
  • -y:直接忽略开机平均值那第一行,只输出后面实时采样
  • -z:把完全没有读写的空闲设备隐藏掉,输出干净很多
  • -x:扩展详细模式!生产排查IO一定要加这个参数,会打印IO平均响应时间await、磁盘繁忙%util

✨实战常用命令,线上排查磁盘慢直接敲这条:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# iostat -dyz 1 3
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)


Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 2.00 0.00 1.50 0.00 0 1 0
nvme0n1 2.00 0.00 1.50 0.00 0 1 0


Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd


Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd

基础字段简单理解:

字段说明
Device块设备名称。nvme0n1是物理NVMe磁盘;dm‑0是LVM逻辑设备(device‑mapper)
tps每秒I/O传输次数,也就是常说的 IOPS。一次传输可以包含多个读写扇区请求
kB_read/s每秒从设备读取的数据量,单位:KB/s
kB_wrtn/s每秒向设备写入的数据量,单位:KB/s
kB_dscd/s每秒丢弃(discarded)的数据量,SSD磁盘的discard/trim回收指令流量
kB_read本次采样周期内,从设备读取的总KB数
kB_wrtn本次采样周期内,向设备写入的总KB数
kB_dscd本次采样周期内,丢弃操作总KB数

💡实战小提示

  1. 上面示例后两行只有表头没有设备数据,代表这一秒磁盘完全没有IO活动,被‑z参数过滤掉了;
  2. 如果要看IO响应时间、磁盘繁忙度,需要再加 -x 扩展参数:iostat -dxyz 1 3,会多出 await、%util 等关键性能指标。

加上 -x 参数之后看到的 await,代表IO平均等待时间。如果这个数值持续几十上百毫秒,说明磁盘已经扛不住压力了。

mpstat:看整体以及每一颗CPU核心状态

有时候业务卡顿,整体CPU使用率看着并不高,top看all汇总id空闲还剩很多,但业务响应就是慢。

典型踩坑场景:多核心机器,整体空闲很高,但某一个CPU核心已经被100%打满。
像单线程应用(老业务程序、Python单进程脚本、部分中间件)只会跑在某一个CPU核心上。这一颗核心跑满100%,但其余核心全程空闲。top展示的是所有CPU的平均值,整体看CPU还有大量空闲,很容易让我们误判,找不到真正瓶颈。

mpstat底层读取/proc目录下内核导出文件拿到CPU数据:

  • 从 /proc/stat 获取处理器整体使用率、中断汇总信息;
  • 从 /proc/interrupts 获取各个CPU每秒接收的中断数量。

默认不加参数时,mpstat只输出整机all的汇总数据,看不到每一颗CPU的细分情况。

下面的命令,每1秒采样,输出3次,打印全部CPU核心:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@localhost ~]# mpstat -P ALL 1 3
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

10:58:25 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:58:26 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:26 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:26 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:26 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:26 PM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00

10:58:26 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:58:27 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:27 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:27 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:27 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:27 PM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00

10:58:27 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:58:28 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:28 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:28 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:28 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:58:28 PM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00

Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00

  • -P ALL:打印全部逻辑CPU;去掉ALL,只输出整机all汇总。
  • -I:查看硬件、软件中断的统计,排查中断暴涨场景。
  • -o JSON:输出JSON格式,写脚本解析非常方便。

关键字段:

字段说明
CPU逻辑CPU编号;all代表全部CPU的汇总统计
%usr用户态CPU占比,业务应用程序执行消耗的CPU时间百分比
%nice调整过nice优先级的进程所占用CPU时间百分比
%sys内核态CPU占比,系统调用、内核代码执行消耗CPU时间
%iowaitCPU等待磁盘IO完成的空闲时间占比,该值高代表存在磁盘IO瓶颈
%irq处理硬件中断消耗的CPU时间占比,硬件设备触发硬中断
%soft处理软件中断消耗的CPU时间占比,网络收发包经常会拉高soft
%steal虚拟化环境下,被宿主机偷走的CPU时间;云虚拟机指标,物理机一般为0
%guest运行KVM虚拟机客户机所消耗CPU时间
%gnice带nice优先级调整的KVM客户机占用CPU时间
%idleCPU空闲时间百分比。单颗CPU此值接近0,说明该核心已经跑满

💡实战小提示

  1. 可以对比top命令的%Cpu(s),两套指标含义完全对应;
  2. 硬件中断%irq、软件中断%soft持续很高,要怀疑出现中断风暴,可能会把个别CPU核心打满,可以搭配参数 -I 进一步查看每CPU中断数量。

✨实战排查套路:

  1. top看整体负载不高,但业务很慢;
  2. 执行 mpstat -P ALL 1 3;
  3. 观察每一行CPU,是否存在个别核心%idle接近0,其他核心空闲很高;
  4. 如果出现这种现象,基本就是单线程程序瓶颈,程序无法利用多核。
  5. 如果怀疑中断问题,加上 -I 参数查看各个CPU的中断接收情况。

⚠️注意:mpstat属于sysstat工具,输出第一行是开机以来平均值,看实时数据要忽略第一行,看后面采样输出。

pidstat:专门盯单个进程的资源开销

很多人有这个困扰:top只能看一瞬间的进程快照,一闪而过的CPU、IO毛刺很难捕捉。iostat、mpstat只能看整机硬件,不知道到底是哪个进程在搞事情。

比如 iostat 看到磁盘IO打满了,整机磁盘压力很大,但几十上百个进程,到底是谁疯狂读写磁盘?
pidstat 就是专门解决这个问题的工具,属于sysstat套件,可以按进程(甚至线程)维度持续采样,分别看CPU、内存缺页、磁盘IO、上下文切换,持续观察一段时间的指标,而不是仅仅一瞬间快照。

底层也是读取 /proc 下面内核导出的统计文件,同样遵守sysstat工具通用规则:输出第一行是系统开机以来总平均值,看实时数据忽略第一行,看后面采样输出。

基础语法格式,和sysstat家族保持一致:

1
pidstat [选项] [-p PID] 采样间隔秒数 采样次数

比如我现在要监控PID=1016这个sshd进程进程,1秒输出一次,一共输出3次:

1
2
3
4
5
6
7
8
9
[root@localhost ~]# pidstat -p 1016 1 3
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

11:07:39 PM UID PID %usr %system %guest %wait %CPU CPU Command
11:07:40 PM 0 1016 0.00 0.00 0.00 0.00 0.00 3 sshd
11:07:41 PM 0 1016 0.00 0.00 0.00 0.00 0.00 3 sshd
11:07:42 PM 0 1016 0.00 0.00 0.00 0.00 0.00 3 sshd
Average: 0 1016 0.00 0.00 0.00 0.00 0.00 - sshd

💡解读这个例子:
PID 1016的sshd进程,在这3秒采样期间完全空闲,没有消耗任何CPU资源,一直躺在3号CPU上待命。
如果你后续在这个机器上ssh登录操作,再跑这条命令,%usr或者%system就会出现数值。

⚠️sysstat通用规则:第一行时间标题那一行,是开机累计平均值,看实时负载,看后面11:07:40、41、42这几行,最后的Average是本次3次采样的均值。

常用参数:

  • -u:CPU统计,默认参数,可以省略
  • -d:查看进程的磁盘IO读写统计,这条需要root权限执行
  • -r:查看内存、页面缺页异常情况
  • -t:把进程下面每一个线程的数据也打印出来,Java程序排查线程问题很好用

✨实战小技巧:不写 -p PID,就只输出采样周期内有资源活动的进程,安静无负载的进程不会打印,输出干净。

字段通俗解释
UID运行该进程的用户ID,这里0代表root用户
PID进程ID,这里是1016,对应sshd服务进程
%usr用户态CPU占比,进程业务代码消耗的CPU时间。这里0.00,代表这一秒sshd没有跑业务代码
%system内核态CPU占比,进程发起系统调用、在内核里执行代码消耗的CPU
%guest虚拟机客户机占用CPU,物理机上一般都是0
%wait进程等待CPU的时间占比。值高说明CPU资源紧张,这个进程排队抢不到CPU时间片
%CPU该进程总CPU使用率 = %usr + %system + %guest。多线程程序这个值可以超过100%
CPU进程当前运行在哪一颗逻辑CPU编号,本例固定跑在3号核
Command进程的命令名称,这里是sshd远程登录服务

✨真实生产排查套路(记住这套组合拳)

  1. iostat 发现整机磁盘IO很高,但不知道是谁干的 → pidstat -d 找到作恶进程;
  2. mpstat 看到CPU打满,top看进程,但进程是Java多线程,不知道哪个线程爆炸 → pidstat -t 展开线程看TID;
  3. vmstat看到si so很高,内存压力大,想看哪个程序频繁触发主缺页 → pidstat -r 看majflt/s指标;
  4. 系统cs(上下文切换)很高,定位是哪一个进程在疯狂切换上下文 → pidstat -w。

⚠️踩坑提醒

  1. -d 磁盘IO统计必须root,普通用户拿到的数据不准;
  2. 第一行是开机以来的累计平均值,分析实时问题,跳过第一行;
  3. pidstat只会输出采样周期内有活动的进程,完全空闲的进程不会打印出来。

sar:sysstat套件里的王牌工具

sar常用方法

咱们前面学了 iostat、mpstat、pidstat,这几个都是当场看实时数据。有个痛点不知道大家有没有遇到过:服务器半夜突然卡顿、业务报错,等你早上上班登录机器,故障已经消失了。现场没了,top、iostat 一跑,负载全都正常,根本不知道刚才发生了啥,这就是典型的故障消失,无据可查。

sar 就是专门解决这个难题的,它是整套 sysstat 工具里功能最强的。
它能干两件大事:

  1. 实时采样:和mpstat、iostat一样,现场抓当前服务器性能指标,CPU、内存、磁盘、网络都能看;
  2. 自动存历史性能日志。系统装好sysstat之后,会自带定时任务,每隔一段时间自动采集系统性能数据,保存成二进制日志文件,存在 /var/log/sa/ 目录。

哪怕故障已经过去几小时甚至大半天,只要日志文件没删,我们直接用sar读取这个历史文件,就能回放当时服务器的状态。可以回看几小时前的CPU使用率、磁盘IO、网络流量,相当于给服务器装了个性能监控录像机。

对比一下:
mpstat、iostat、pidstat:直播,只能看当下,故障一过,数据直接消失,没法回看。
sar:直播+录像,既能实时看现场,还自动保存录像,事后复盘历史故障。

实时采集示例:1秒采集一次,采集3次,同时把全部数据保存到 lixiaohui.out 文件,方便后续回看

1
2
3
4
5
6
7
8
[root@localhost ~]# sar -o lixiaohui.out 1 3
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

11:14:12 PM CPU %user %nice %system %iowait %steal %idle
11:14:13 PM all 0.00 0.00 0.50 0.00 0.00 99.50
11:14:14 PM all 0.00 0.00 0.25 0.00 0.00 99.75
11:14:15 PM all 0.00 0.00 0.00 0.00 0.00 100.00
Average: all 0.00 0.00 0.25 0.00 0.00 99.75
字段通俗解释
CPUall 代表所有逻辑CPU汇总;sar也可以单独看每一颗CPU的数据
%user用户态CPU占比,业务应用代码消耗的CPU时间,用户程序跑在这里
%nice调整过nice优先级的进程,占用的CPU时间百分比
%system内核态CPU占比,进程调用系统调用、内核处理中断等内核代码消耗CPU。这个高,说明大量内核操作
%iowaitCPU在空闲、但是在等待磁盘IO完成的时间占比。数值高 = 磁盘拖慢程序
%steal虚拟化/云主机专用指标:宿主机抢占偷走的CPU时间;物理机一般为0
%idleCPU空闲时间占比,啥活都没干。这个数值越低,CPU越忙

💡 解读当前样例:
机器整体负载很低,%idle接近100%。只有少量%system,是系统内核轻微操作,没有业务程序消耗CPU,没有IO等待,虚拟机也没有被宿主机抢资源。

✨小知识点:
-o 输出的是二进制文件,不是文本,不能直接cat打开,必须用 sar -f 读取。
比如事后复盘:sar -f lixiaohui.out,就能重新把刚才这3条记录打印出来,和系统自动生成的sa日志原理一模一样。

1
2
3
4
5
6
7
8
[root@localhost ~]# sar -f lixiaohui.out
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

11:14:12 PM CPU %user %nice %system %iowait %steal %idle
11:14:13 PM all 0.00 0.00 0.50 0.00 0.00 99.50
11:14:14 PM all 0.00 0.00 0.25 0.00 0.00 99.75
11:14:15 PM all 0.00 0.00 0.00 0.00 0.00 100.00
Average: all 0.00 0.00 0.25 0.00 0.00 99.75

sar支持非常多维度指标:

参数功能
-b块设备IO统计
-B内存分页swap换入换出
-d磁盘设备详细统计
-n网络流量、网络错误统计
-r内存使用情况
-q运行队列、负载平均值,看CPU排队情况

系统默认历史日志存放在 /var/log/sa/ 目录下面,文件名 sa26 代表当月3号的性能数据。想要复盘26号那天系统负载情况,执行:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# systemctl status sysstat
○ sysstat.service - Resets System Activity Logs
Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; preset: enabled)
Active: inactive (dead)
[root@localhost ~]# systemctl restart sysstat
[root@localhost ~]# ls /var/log/sa/
sa26
[root@localhost ~]# sar -q -f /var/log/sa/sa26
Linux 6.12.0-211.16.1.el10_2.0.1.x86_64 (localhost.localdomain) 09/26/2026 _x86_64_ (4 CPU)

11:17:51 PM LINUX RESTART (4 CPU)

✨小提示:很多新人不知道sar可以读历史文件,故障消失之后只能干瞪眼,学会这条命令,相当于服务器自带黑匣子。

sar收集和查询数据要点

sar命令不是自己一直蹲在后台跑,是靠 cron或timer 定时任务,非交互模式自动采集。

简单一句话:sar负责查看数据,真正采集数据的是sadc,由sa1、sa2脚本配合cron等工具来定时调度。

咱们以前学老版本CentOS7、RHEL8的时候,sysstat安装完,定时任务配置就在 /etc/cron.d/sysstat。

但是Rocky10、RHEL10这一类新版本,这个文件和路径已经取消了,目录里找不到这个cron配置文件!

很多同学跟着老教材敲命令:cat /etc/cron.d/sysstat,直接提示 No such file or directory,不是你装错了,是新版sysstat不再依靠cron定时任务,换成了systemd的timer定时器。

一句话总结:

  • 老版本(CentOS7/RHEL8):用 /etc/cron.d/sysstat + cron 调度 sa1、sa2
  • 新版本(RHEL9、EL10):移除了cron文件,改用 systemd service + systemd timer 来定时执行sa1采集

新版对应的两个systemd单元文件:

  1. sysstat.service:负责一次性初始化、创建日志目录
  2. sysstat-collect.timer:定时器,用来定时触发采集,默认每10分钟执行一次sa1采集

配套的采集服务单元:sysstat-collect.service,内部调用sa1脚本。

还有一个 sysstat-summary.timer,每天执行sa2,生成每日汇总报告。

看采集定时器状态:

1
2
3
4
5
6
[root@localhost ~]# systemctl list-timers sysstat-collect.timer
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sat 2026-09-26 23:30:00 CST 6min Sat 2026-09-26 23:20:23 CST 3min 33s ago sysstat-collect.timer sysstat-collect.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

字段解释:

  1. NEXT:下一次定时器触发的时间:2026-09-26 23:30:00
  2. LEFT:距离下次采集还剩多久,这里还有6分钟
  3. LAST:上一次定时器触发执行的时间:23:20:23
  4. PASSED:距离上次执行过去了 3分33秒
  5. UNIT:定时器单元名称 sysstat-collect.timer
  6. ACTIVATES:定时器触发之后,会启动 sysstat-collect.service,这个服务内部调用sa1脚本,再调用sadc采集性能数据,写入sa日志。

大家看时间间隔:上次23:20,下一次23:30,正好间隔10分钟,就是sysstat默认的采集周期,完全符合预期。

查看sysstat-collect.timer单元文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost ~]# cat /usr/lib/systemd/system/sysstat-collect.timer
# /usr/lib/systemd/system/sysstat-collect.timer
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
#
# sysstat-12.7.6 systemd unit file:
# Activates activity collector every 10 minutes

[Unit]
Description=Run system activity accounting tool every 10 minutes

[Timer]
OnCalendar=*:00/10

[Install]
WantedBy=sysstat.service

看下面这个时间的安排:

1
OnCalendar=*:00/10

OnCalendar 是systemd定时器的时间语法。
*:00/10 拆解含义:

  • *:代表每一小时
  • :00:小时内的分钟起点,0分
  • /10:每隔10分钟执行一次

整体含义:每小时的 0分、10分、20分、30分、40分、50分 触发任务。
比如 23:00、23:10、23:20、23:30、23:40、23:50,这就是为什么刚才我们看到,上一次23:20,下一次23:30,正好间隔10分钟。

注意:OnCalendar 是基于日历的定时,和普通cron写法很像,但语法是systemd独有的。

[Install] 安装段注意:

1
WantedBy=sysstat.service

WantedBy 定义这个timer的依赖挂载点。
意思是:当 sysstat.service 启动的时候,会“拉起来”这个 sysstat-collect.timer 定时器。
我们执行 systemctl enable sysstat 的时候,就会自动把这个timer设为开机随sysstat一起启用。

对应老版本cron对比记忆:
老系统写在 /etc/cron.d/sysstat 里面的 cron表达式 */10 * * * *,效果和这里 OnCalendar=*:00/10 是等效的,都是10分钟跑一次采集,只是一个是crond调度,一个是systemd timer调度。

一个重要知识点:

修改这个timer文件之后,不会自动生效。
如果你改动了里面时间,需要重载systemd配置:

1
systemctl daemon-reload

然后重启定时器。

但是一般不建议随便改这个文件,官方单元文件属于系统文件,更新软件包会覆盖。如果要自定义采集周期,推荐放自定义文件到 /etc/systemd/system/ 下面。

整条执行链路再串一遍:

到了定时时间 → sysstat-collect.timer 触发 → 启动 sysstat-collect.service → 执行sa1脚本 → sadc采集性能数据 → 写入 /var/log/sa/ 的sa二进制日志。

了解sar的调度和服务

查看真正执行采集的服务单元:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# cat /usr/lib/systemd/system/sysstat-collect.service
# /usr/lib/systemd/system/sysstat-collect.service
# (C) 2014 Tomasz Torcz <tomek@pipebreaker.pl>
#
# sysstat-12.7.6 systemd unit file:
# Collects system activity data
# Activated by sysstat-collect.timer unit

[Unit]
Description=system activity accounting tool
Documentation=man:sa1(8)
After=sysstat.service

[Service]
Type=oneshot
User=root
ExecStart=/usr/lib64/sa/sa1 1 1

打开 sysstat-collect.service 看里面内容,里面就是去调用 /usr/lib64/sa/sa1,底层sa1、sadc这套逻辑没变,只是调度器从cron换成systemd timer。

After=sysstat.service:启动顺序控制。意思是:必须等 sysstat.service 启动完成之后,才允许运行这个采集服务。保证日志目录、基础环境提前准备好,避免sa1执行时报目录不存在的错误。
Type=oneshot oneshot 是systemd里一次性任务类型。代表:这个服务执行一条命令,命令跑完、退出,服务就结束。不是常驻后台持续运行。
ExecStart=/usr/lib64/sa/sa1 1 1这是最重要一行,定义要执行的命令。调用sa1脚本,后面两个参数 1 1:

  • 第一个1:采样间隔,采集1秒的数据
  • 第二个1:采集次数,只采集1组样本

翻译成人话:sa1内部调用sadc,采集1秒的系统性能数据,采集1次,追加写入 /var/log/sa/ 下面当天的sa二进制日志文件。

整条链路串起来复习一遍:

  1. sysstat-collect.timer 闹钟到点(每10分钟)
  2. 触发启动 sysstat-collect.service
  3. 检查依赖:确认sysstat.service已经启动
  4. 以root执行 sa1 1 1
  5. sa1调用底层sadc采集1秒性能指标
  6. 数据追加写入 /var/log/sa/saDD 二进制文件
  7. sa1执行完毕,进程退出。oneshot任务结束,等待下一次timer闹钟

我们可以直接手动执行这一行命令,模拟定时器触发的动作:

1
/usr/lib64/sa/sa1 1 1

执行完立刻就会生成/更新sa日志,用来排查问题,非常方便。

这个service本身不会自动周期性运行!必须依靠timer去触发。只enable service,不启用timer,不会自动采集。

底层组件不变:sa1调用sadc采集二进制数据,写入/var/log/sa/,原理和老版本一模一样,只是触发方式换了。

sa1和sa2

  1. sa1 脚本:它内部调用 sadc(System Activity Data Collector,系统活动数据采集器)。sadc才是底层采集工具,抓取系统性能指标,默认单次采样间隔1秒。
    默认cron每10分钟跑一次sa1,采集到的数据追加写入二进制sa日志文件。
    也就是咱们前面看到的 /var/log/sa/saDD。

  2. sa2 脚本:它的作用不是持续采集,是生成每日汇总报告,把全天性能统计写到日志文件,文件名格式两种:

  • 简写:saDD,DD代表当月几号,比如26号就是 sa26
  • 长格式:saYYYYMMDD,年+月+日,比如sa20260926

这里大家要分清角色,很多人容易搞混:

  • sar:查看、回放已经采集好的数据,不负责采集
  • sadc:底层采集二进制性能数据的核心程序
  • sa1:调度sadc,定时采集,追加数据到sa文件
  • sa2:生成每日报告文件
  • cron:定时器,到点自动触发sa1、sa2执行,全程非交互,不需要人手动敲命令

补充一个关键点:这整套就是非交互方式运行sar体系。不需要我们登录服务器、手动敲sar命令;cron或timer到点自动调用脚本采集,后台默默记录性能数据,等后面出故障了,我们再用sar去读取这些保存好的二进制日志复盘。

sysstat自动定时采集机制

现在新版RHEL10不再使用cron,改用 systemd timer 定时器。
sysstat装好之后,默认每10分钟自动采集一次性能指标,写入日志文件。

⚠️重要提醒:不要直接修改 /usr/lib/systemd/system/sysstat-collect.timer,软件包升级会直接覆盖你的修改!
如果想修改采集间隔,复制一份到 /etc/systemd/system/ 目录再编辑。修改完重载systemd配置:

1
2
3
systemctl daemon-reload
# 重新启用定时器
systemctl enable --now sysstat-collect.timer

日志保留多少天,配置文件在 /etc/sysconfig/sysstat,修改里面 HISTORY="28",代表保存28天历史性能日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# grep -v ^# /etc/sysconfig/sysstat

HISTORY=28

COMPRESSAFTER=31

SADC_OPTIONS=" -S DISK"

SA_DIR=/var/log/sa

ZIP="xz"



DELAY_RANGE=0

UMASK=0022

好了,篇幅很长了,就到这吧,后面我们再聊聊PCP这个神器。