CPU性能篇-平均负载与案例分析-Day 01

1. 平均负载

1.1 什么是平均负载

平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。

1.1.1 什么是可运行状态

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

1.1.2 什么是不可中断状态

不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 top 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。
 

比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。

1.1.3 总结

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

  • 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
  • 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
  • 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。

1.2 平均负载为多少时合理

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

1.2.1 查看系统cpu逻辑个数

[root@test-apollo ~]# grep 'model name' /proc/cpuinfo | wc -l # 这里为4个CPU
4

# 用top也可以 但是cpu如果很多的时候,top可能显示不完全
top - 17:27:31 up 3 days,  2:00,  2 users,  load average: 0.06, 0.03, 0.05
Tasks: 189 total,   1 running, 188 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.3 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.3 us,  0.7 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.3 us,  0.7 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

1.3 分析平均负载的三个时间段

  • 如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
  • 但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。
  • 反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了。

1.4 如何关注生产的平均负载

当平均负载高于 CPU 数量 70% 的时候,就应该分析排查负载高的问题了,因为一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。
 

但 70% 这个数字并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显升高趋势时,比如说负载翻倍了,再去做分析和调查。

2. 平均负载与 CPU 使用率的区别

2.1 平均负载

平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。

2.2 CPU 使用率

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

  • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
  • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
  • 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。

3. 平均负载案例分析

3.1 使用工具及系统

3.1.1 系统、配置及使用的软件

系统:CentOS 7(linux都可以)
工具:iostat、mpstat、pidstat等
机器配置:2 CPU,8GB 内存。
安装包:stress 和 sysstat 包。

3.1.2 工具介绍

  • stress包:是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
  • stress-ng:stress的进阶版,更加强大,弥补的使用stress包测试IO时,%iowait无法升高的问题。
  • sysstat包:包含了常用的 Linux 性能工具,用来监控和分析系统的性能。我们的案例会用到这个包的两个命令 mpstat 和 pidstat。
  • mpstat:是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
  • pidstat:是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
  • iotop: 是一个类似 top 的工具,用来显示实时的磁盘活动。

3.1.3 注意事项

每个场景都需要开三个终端,登录到同一台 Linux 机器中。

3.1.4 工具包安装与升级

3.1.4.1 sysstat包升级

由于CentOS 7 自带的sysstat包版本太低,导致pidstat输出中没有%wait,升级到11.5.5版本以后就可以看到。
官网地址:Sysstat Home Page
下载最新稳定版本即可。

[root@test-apollo ~]# wget http://pagesperso-orange.fr/sebastien.godard/sysstat-12.4.5.tar.xz
[root@test-apollo ~]# rpm -e --nodeps sysstat
[root@test-apollo ~]# yum -y install gcc gcc-c++
[root@test-apollo ~]# tar Jxf sysstat-12.4.5.tar.xz
[root@test-apollo ~]# cd sysstat-12.4.5/
[root@test-apollo sysstat-12.4.5]# ./configure --prefix=/usr
[root@test-apollo sysstat-12.4.5]# make install
[root@test-apollo ~]# pidstat -V
sysstat version 12.4.5
(C) Sebastien Godard (sysstat <at> orange.fr)

3.1.4.2 stress-ng包安装

在虚拟机测试过程中使用stress,会导致iowait无法升高,因为案例中stress使用的是 sync() 系统调用,它的作用是刷新缓冲区内存到磁盘中。对于新安装的虚拟机,缓冲区可能比较小,无法产生大的IO压力,这样大部分就都是系统调用的消耗了。

解决办法:使用stress的下一代stress-ng,它支持更丰富的选项,比如 stress-ng -i 1 --hdd 1 --timeout 600(--hdd表示读写临时文件)。

[root@test-apollo ~]# yum -y install stress-ng

3.1.4.3 stress包安装
[root@test-apollo ~]# yum -y install stress

3.2 场景一:CPU 密集型进程

3.2.1 在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的场景

[root@test-apollo ~]# stress --cpu 1 --timeout 600
stress: info: [1630] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd

3.2.2 在第二个终端运行 uptime 查看平均负载的变化情况

[root@test-apollo ~]# watch -d uptime # -d, 参数表示高亮显示变化的区域
……省略部分输出
17:58:42 up 8 min,  3 users,  load average: 1.22, 0.76, 0.35 # 1分钟的负载,会慢慢变成1或者超过

3.2.3 mpstat 查看 CPU 使用率的变化情况(终端三)

从终端三中可以看到,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。

[root@test-apollo ~]# mpstat -P ALL 5 # -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
Linux 3.10.0-1062.el7.x86_64 (test-apollo)      08/08/2022      _x86_64_        (2 CPU)

05:59:35 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
05:59:40 PM  all   50.20    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   49.60
05:59:40 PM    0    0.20    0.00    0.40    0.00    0.00    0.00    0.00    0.00    0.00   99.40
05:59:40 PM    1  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00

  • %usr:用户级别(应用程序)运行使用 CPU 总时间的百分比。
  • %nice:在用户级别,用于 nice 操作所占用 CPU 总时间的百分比。nice 操作是用于调整进程优先级的。
  • %sys:系统内核运行占用 CPU 总时间的百分比。包括内核函数调用、中断处理等系统层面的操作。
  • %iowait:等待 I/O 操作完成的时间占 CPU 时间的百分比。如果该值过高,通常表示硬盘存在 I/O 瓶颈。
  • %irq:处理硬件中断的时间占 CPU 时间的百分比。
  • %soft:处理软件中断的时间占 CPU 时间的百分比。
  • %steal:被其他虚拟机偷走的 CPU 时间百分比(在虚拟化环境中才有意义)。
  • %guest:运行虚拟机客户操作系统所占用的 CPU 时间百分比。
  • %gnice:用于 guest nice 操作的 CPU 时间百分比,类似于 %nice,但针对虚拟机中的进程。
  • %idle:CPU 空闲时间占用 CPU 总时间的百分比。

3.2.4 用 pidstat 来查询使用cpu100%的进程

[root@test-apollo ~]# pidstat -u 5 1 # 间隔5秒后输出一组数据
Linux 3.10.0-1062.el7.x86_64 (test-apollo)      08/09/2022      _x86_64_        (2 CPU)

11:30:46 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
11:30:51 AM     0      3757  100.00    0.00    0.00    0.00  100.00     0  stress  # 从这里可以明显看到,stress 进程的 CPU 使用率为 100%。
11:30:51 AM     0      3826    0.00    0.20    0.00    0.00    0.20     1  pidstat

Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0      3757  100.00    0.00    0.00    0.00  100.00     -  stress
Average:        0      3826    0.00    0.20    0.00    0.00    0.20     -  pidstat
  • UID:进程所属用户的用户ID。
  • PID:是进程ID(Process ID)。
  • %usr:进程在用户态(也就是执行用户空间代码,像普通应用程序自身的业务逻辑代码等)使用 CPU 的时间占总 CPU 时间的百分比,数值越高说明该进程在用户态占用 CPU 资源越多,用于执行自身任务越频繁。
  • %system:进程在内核态(执行系统调用、驱动程序等内核相关代码)使用 CPU 的时间占总 CPU 时间的百分比,体现了该进程与操作系统内核交互、请求内核服务等操作消耗 CPU 资源的情况。
  • %guest:如果系统运行在虚拟化环境中,此指标表示进程运行在虚拟机客户操作系统里所占用的 CPU 时间百分比,在非虚拟化环境下通常为 0。
  • %wait:进程处于等待 I/O(磁盘 I/O、网络 I/O 等)或者其他资源完成相应操作而空闲的时间占总 CPU 时间的百分比,反映了进程等待外部资源的情况,较高的 %wait 值可能意味着存在 I/O 瓶颈等影响进程执行的因素。
  • %CPU:是 %usr、%system、%guest 这几个百分比的总和,综合体现了进程总体占用 CPU 资源的比例情况,方便直观判断进程对 CPU 资源的依赖程度和消耗情况。
  • CPU:显示该进程当前是运行在哪个 CPU 核心上,对于多核系统,可以了解不同进程在各个 CPU 核心上的分布情况,有助于分析 CPU 资源是否均衡利用等问题。
  • Command:就是启动该进程对应的命令名称,通过这个能快速知晓是哪个具体的应用或者工具对应的进程在消耗资源,便于进一步排查和分析其功能、是否正常运行等相关情况。 

3.3 场景二:I/O 密集型进程

3.3.1 模拟I/O 压力

首先还是运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync。

[root@test-apollo ~]# stress-ng -i 1 --hdd 1 --timeout 600
stress-ng: info:  [3454] dispatching hogs: 1 hdd, 1 io

3.3.2 查看平均负载

在第二个终端运行 uptime 查看平均负载的变化情况。

[root@test-apollo ~]# watch -d uptime
……省略部分输出
18:08:50 up 18 min,  3 users,  load average: 1.13, 0.92, 0.64 # 1分钟的负载会慢慢变成1甚至超过

3.3.3 查看cpu使用率

第三个终端运行 mpstat 查看 CPU 使用率的变化情况

[root@test-apollo ~]# mpstat -P ALL 5 1 # 从下图可以看到,磁盘IO等待已经%97.8了
Linux 3.10.0-1062.el7.x86_64 (test-apollo)      08/09/2022      _x86_64_        (2 CPU)

10:17:11 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
10:17:16 AM  all    0.10    0.00    0.90   49.05    0.00    0.00    0.00    0.00    0.00   49.95
10:17:16 AM    0    0.20    0.00    1.80   97.80    0.00    0.20    0.00    0.00    0.00    0.00
10:17:16 AM    1    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.80

Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all    0.10    0.00    0.90   49.05    0.00    0.00    0.00    0.00    0.00   49.95
Average:       0    0.20    0.00    1.80   97.80    0.00    0.20    0.00    0.00    0.00    0.00
Average:       1    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.80

从上面可以看到,1 分钟的平均负载会慢慢增加到 1.13,其中 iowait 高达 97.80%。这说明,平均负载的升高是由于 iowait 的升高。


3.3.4 pidstat找到高IO的元凶

-d参数,是专门用来监控磁盘IO的。

通过下图,每2秒采集一次,一共统计10次,就能清楚的看到,stress-ng进程有大量的写入操作,基本可以确认就是它的磁盘操作,造成了平均负载升高。

3.3.5 iotop找到高IO的元凶

iotop是实时监控的,所以需要一直看着,如果IO操作是非持续的,可能需要一直看着。

下图可以看到,磁盘去取基本没有,但是当前的瞬时写入,最高到了82.15M/S,而监控捕捉到的历史磁盘写入,最高到了136.76M/S,对应的程序是stress-ng-hdd,[run]表示正在运行。

3.4 场景三:大量进程的场景

当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。

3.4.1 使用 stress模拟 8 个进程

[root@test-apollo ~]# stress -c 8 --timeout 600
stress: info: [4544] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd

3.4.2 查看系统负载

由于系统只有 2 个 CPU,明显比 8 个进程要少得多,因而,系统的 CPU 处于严重过载状态,平均负载高达 6.85

[root@test-apollo ~]# uptime
 10:32:36 up 16:42,  4 users,  load average: 6.85, 3.79, 2.42

3.4.3 查看进程

从下面返回的结果可以看出,8 个进程(stress)在争抢 2 个 CPU,每个进程等待 CPU 的时间( %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。

[root@test-apollo ~]# pidstat -u 5 1
Linux 3.10.0-1062.el7.x86_64 (test-apollo)      08/09/2022      _x86_64_        (2 CPU)

11:35:34 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
11:35:39 AM     0      3996   24.95    0.00    0.00   74.85   24.95     1  stress
11:35:39 AM     0      3997   24.95    0.00    0.00   75.25   24.95     0  stress
11:35:39 AM     0      3998   24.95    0.00    0.00   75.25   24.95     0  stress
11:35:39 AM     0      3999   24.95    0.00    0.00   75.25   24.95     0  stress
11:35:39 AM     0      4000   24.95    0.00    0.00   74.85   24.95     1  stress
11:35:39 AM     0      4001   24.95    0.00    0.00   75.05   24.95     1  stress
11:35:39 AM     0      4002   24.75    0.00    0.00   74.45   24.75     0  stress
11:35:39 AM     0      4003   24.95    0.00    0.00   75.25   24.95     1  stress
11:35:39 AM     0      4006    0.00    0.20    0.00    0.00    0.20     0  pidstat

Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0      3996   24.95    0.00    0.00   74.85   24.95     -  stress
Average:        0      3997   24.95    0.00    0.00   75.25   24.95     -  stress
Average:        0      3998   24.95    0.00    0.00   75.25   24.95     -  stress
Average:        0      3999   24.95    0.00    0.00   75.25   24.95     -  stress
Average:        0      4000   24.95    0.00    0.00   74.85   24.95     -  stress
Average:        0      4001   24.95    0.00    0.00   75.05   24.95     -  stress
Average:        0      4002   24.75    0.00    0.00   74.45   24.75     -  stress
Average:        0      4003   24.95    0.00    0.00   75.25   24.95     -  stress
Average:        0      4006    0.00    0.20    0.00    0.00    0.20     -  pidstat

4. 总结

4.1 平均负载

平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:

  • 平均负载高有可能是 CPU 密集型进程导致的;
  • 平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O(磁盘或网络或其他IO相关的硬件设备) 更繁忙了;
  • 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
  • 当发现负载高的时候,可以使用 mpstat、pidstat 等工具,辅助分析负载的来源。

4.2 排查命令

mpstat:查看CPU使用率的变化,有没有io等待啥的。

pidstat:

        -u: 查看cpu使用的情况。

        -d:查看磁盘使用率的情况。

5. 使用百分比公式

(1.73-1)/1*100%=73%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值