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

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

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

sysstat 工具包介绍

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这个神器。