如何使用性能分析工具观察cpu性能指标

前言:为了更好配置分布式储存集群的运行参数,使用性能分析工具观察业务环境是一种必要的手段

op 或者 uptime

02:34:03              //当前时间
up 2 days, 20:14      //系统运行时间
1 user                //正在登录用户数

load average: 0.63, 0.83, 0.88
依次则是过去 1 分钟、5 分钟、15 分钟的平均负载(Load Average)

 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系,所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。

 

可运行状态

可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程

可中断的睡眠状态的进程会睡眠直到某个条件变为真,如产生一个硬件中断、释放进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。

 

不可中断状态

不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的

那就是把信号传递到这种睡眠状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。

比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制

既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。
比如当平均负载为 2 时,意味着什么呢?

1.在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。

2.在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。

3.而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。 ====》 (平均负载比cpu个数大,过载 )

所以 平均负载最理想的情况是等于 CPU 个数

grep 'model name' /proc/cpuinfo | wc -l //可查看cpu数目 

12 //12核

 

如何观察数值

//假设单核情况
root@xxxx:~# uptime
09:28:31 up 1 day, 10:31,  2 users,  load average: 1.96, 1.29, 1.59

 

假设是单核情况下, 1分钟下来有96%超载,5分钟下来有29%超载,15分钟下来有59%超载

1.当三者相差不大,说明系统的平均负载稳定。

2.当前1分钟比后两者小的时候,说明系统趋于降低

3.如果1分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加

经验值之谈,一旦平均负载达到CPU数量的前后 75%左右,需要排查负载高的问题。

 

平均负载与 CPU 使用率区别

CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应

CPU使用率:单位时间内cpu繁忙情况的统计

情况1:CPU密集型进程,CPU使用率和平均负载基本一致

情况2:IO密集型进程,平均负载升高,CPU使用率不一定升高

情况3:大量等待CPU的进程调度,平均负载升高,CPU使用率也升高

 

场景模拟

借用iostat mpstat pidstat可以分析出平均负载升高的原因。

模拟一下使用场景

root@xxxx:~# apt install sysstat //常用的 Linux 性能工具,用来监控和分析系统的性能,包含两个命令 mpstat 和 pidsta
root@xxxx:~# apt install stress //一个 Linux 系统压力测试工具

 

前提环境:

机器配置:4 CPU,8GB 内存。

root@xxxx:~# uptime
 11:36:37 up 13 days, 29 min,  3 users,  load average: 0.06, 0.06, 0.01

 

CPU 的用户层(%usr)使用率;

CPU 的系统层(%sys)使用率;

CPU 的 I/0 - 等待(%iowait);

CPU 的空闲率(%idle);

首先,我们在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的CPU 密集型进程场景:

//一终端执行
root@xxxx:~# stress --cpu 4 --timeout 555
stress: info: [4563] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd

//另一终端

root@xxxx:~# watch -d uptime

Every 2.0s: uptime xxxx: Tue Dec 22 11:43:36 2020

 11:43:36 up 13 days, 36 min,  3 users,  load average:  4.13, 1.28, 0.46




// 另一终端2
//-P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
root@xxxx:~# mpstat -P ALL 5
11:45:26 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11:45:31 AM  all   99.65    0.00    0.25    0.00    0.00    0.10    0.00    0.00    0.00    0.00
11:45:31 AM    0   99.40    0.00    0.40    0.00    0.00    0.20    0.00    0.00    0.00    0.00
11:45:31 AM    1   99.60    0.00    0.40    0.00    0.00    0.00    0.00    0.00    0.00    0.00
11:45:31 AM    2   99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00
11:45:31 AM    3   99.80    0.00    0.00    0.00    0.00    0.20    0.00    0.00    0.00    0.00


//从这里可以明显看到,stress 进程的 CPU 使用率接近 100%。
root@xxxx:~# pidstat -u 5 1
Linux 4.15.0-66-generic (xxxx)     12/22/2020      _x86_64_        (4 CPU)

11:48:58 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
11:49:03 AM     0      2049    0.00    0.20    0.00    0.00    0.20     2  kworker/2:0
11:49:03 AM 64045      3358    0.60    0.20    0.00    0.00    0.80     3  ceph-mon
11:49:03 AM     0      4564   98.41    0.20    0.00    1.39   98.61     0  stress
11:49:03 AM     0      4565   98.81    0.00    0.00    0.99   98.81     1  stress
11:49:03 AM     0      4566   98.21    0.00    0.00    1.39   98.21     0  stress
11:49:03 AM     0      4567   99.20    0.00    0.00    0.60   99.20     2  stress
11:49:03 AM     0      5131    0.20    0.20    0.00    0.40    0.40     0  watch
11:49:03 AM     0      7419    0.20    0.40    0.00    0.00    0.60     3  pidstat
11:49:03 AM     0     26649    0.00    0.20    0.00    0.00    0.20     0  kworker/0:1
11:49:03 AM     0     26658    0.20    0.20    0.00    0.20    0.40     1  sshd
11:49:03 AM 64045     30555    0.60    0.00    0.00    0.00    0.60     1  ceph-osd
//

 

可以从 load average: 4.13 以及 mpstat 的usr 看得出负载场景基本符合CPU 密集型进程 ,pidstat可以看得出是 stress 导致占用率过高。

然后模拟一个I/O 密集型进程

//一终端执行
//root@xxxx:~# stress -i 1 --timeout 600  // 因为 stress 使用的sync系统调用,刷新缓冲区到磁盘。有可能因缓冲区数据量小无法看到io_wait明显变化
root@xxxx:~# stress-ng -i 1 --hdd 1 --timeout 555
stress-ng: info:  [9211] dispatching hogs: 1 io, 1 hdd

//另一终端

root@xxxx:~# watch -d uptime
 16:46:09 up 13 days,  5:38,  3 users,  load average: 2.91, 2.56, 1.10




// 另一终端2
//-P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
root@xxxx:~# mpstat -P ALL 5
Linux 4.15.0-66-generic (ECSab169d)     12/22/2020      _x86_64_        (4 CPU)
04:44:02 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:44:07 PM  all    1.35    0.00   29.50   26.74    0.00    0.21    0.52    0.00    0.00   41.68
04:44:07 PM    0    2.05    0.00   30.12   26.23    0.00    0.20    0.61    0.00    0.00   40.78
04:44:07 PM    1    0.40    0.00   30.51   51.72    0.00    0.00    0.81    0.00    0.00   16.57
04:44:07 PM    2    0.84    0.00   19.29   19.08    0.00    0.00    0.42    0.00    0.00   60.38
04:44:07 PM    3    1.96    0.00   38.26    8.48    0.00    0.65    0.22    0.00    0.00   50.43


root@xxxx:~# pidstat -u 5 1
04:43:15 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
04:43:20 PM     0       388    0.00    0.20    0.00    0.00    0.20     0  kworker/0:1H
04:43:20 PM     0     11841    0.00    2.00    0.00    0.00    2.00     1  kworker/1:2
04:43:20 PM     0     12449    0.00    5.40    0.00    0.40    5.40     1  stress-ng-io
04:43:20 PM     0     12450    2.60   60.20    0.00    0.80   62.80     0  stress-ng-hdd
04:43:20 PM     0     22527    0.20    0.20    0.00    0.00    0.40     1  sshd
04:43:20 PM 64045     30555    0.20    0.40    0.00    0.00    0.60     1  ceph-osd

 

从这里可以看到,1 分钟的平均负载会慢慢增加到 2.91,其中一个 CPU 的系统 CPU 使用率升高到了 30.51,而 iowait 高达 51.72%。这说明,平均负载的升高是由于 iowait 的升高,pidstat 定位到stress进程。

模拟一个大量进程场景

//一终端执行
root@xxxx:~# stress -c 8 --timeout 555
17:00:26 up 13 days,  5:53,  3 users,  load average: 7.90, 4.95, 3.04

//另一终端

root@xxxx:~# watch -d uptime
17:00:49 up 13 days,  5:53,  3 users,  load average: 7.94, 5.20, 3.17


root@xxxx:~# pidstat -u 5 1
04:43:15 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
04:43:20 PM     0       388    0.00    0.20    0.00    0.00    0.20     0  kworker/0:1H
04:43:20 PM     0     11841    0.00    2.00    0.00    0.00    2.00     1  kworker/1:2
04:43:20 PM     0     12449    0.00    5.40    0.00    0.40    5.40     1  stress-ng-io
04:43:20 PM     0     12450    2.60   60.20    0.00    0.80   62.80     0  stress-ng-hdd
04:43:20 PM     0     22527    0.20    0.20    0.00    0.00    0.40     1  sshd
04:43:20 PM 64045     30555    0.20    0.40    0.00    0.00    0.60     1  ceph-osd


05:01:33 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
05:01:38 PM 64045      3358    0.40    0.20    0.00    0.00    0.60     3  ceph-mon
05:01:38 PM     0      5131    0.60    0.20    0.00    0.60    0.80     1  watch
05:01:38 PM     0      9303    0.00    0.20    0.00    0.00    0.20     2  kworker/u8:3
05:01:38 PM     0     13169    0.00    0.20    0.00    0.00    0.20     0  kworker/0:2
05:01:38 PM     0     18138   48.91    0.00    0.00   51.09   48.91     1  stress
05:01:38 PM     0     18139   49.11    0.00    0.00   50.70   49.11     2  stress
05:01:38 PM     0     18140   48.71    0.00    0.00   50.89   48.71     0  stress
05:01:38 PM     0     18141   50.10    0.00    0.00   49.50   50.10     3  stress
05:01:38 PM     0     18142   47.91    0.00    0.00   51.89   47.91     3  stress
05:01:38 PM     0     18143   49.11    0.00    0.00   51.09   49.11     1  stress
05:01:38 PM     0     18144   52.29    0.00    0.00   47.71   52.29     0  stress
05:01:38 PM     0     18145   49.30    0.00    0.00   50.70   49.30     2  stress
05:01:38 PM     0     20608    0.00    0.20    0.00    0.20    0.20     0  pidstat
05:01:38 PM     0     22527    0.00    0.20    0.00    0.00    0.20     2  sshd
05:01:38 PM 64045     30555    0.40    0.00    0.00    0.00    0.40     1  ceph-osd

 

可以看出,8 个进程在争抢 4 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 50%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。

 

总结

1.CPU密集型进程: 查看 mpstat 是否存在某个CPU %usr 很高但是iowait 很低 , pidstat 定位具体进程(瓶颈不在io)

2.IO密集型进程: mpstat 观察是否有某个cpu的%iowait很高,同时%usr也较高, pidstat 定位具体进程

3.大量进程 : 观察 mpstat 有可能iowait 很低, 但是从 pidstat 看出%wait很高,侧面表现出进程出现竞争cpu

用到命令

lscpu、 grep ‘model name’ /proc/cpuinfo | wc -l : cpu核数

watch -d uptime : 持续观察平均负载

pidstat -u 5 1 : 监测进程对应负载状态,进程性能分析工具

mpstat -P ALL 5 : cpu总体状态 多核cpu性能分析工具,-P ALL监视所有cpu

strees : -c 产生多个worker进程;—cpu-method 使用哪种算法来运行压力测试,包括pi, crc16, fft等等,all选择全部;—sock 调用socket相关函数产生压力; -t, —timeout 等待xx微秒后才开始运行;-i, —io N spawn N workers spinning on sync()

上一篇:Day 3 - 电子相册搭建(人脸、表情识别)


下一篇:popen、system