Cpu负载(load average)介绍
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。因此,你可以简单理解为,平均负载其实就是平均活跃进程数。平均活跃进程数,直观上的理解就是单位时间内的活跃进程数,但它实际上是活跃进程数的指数衰减平均值。这个“指数衰减平均”的详细含义你不用计较,这只是系统的一种更快速的计算方式,你把它直接当成活跃进程数的平均值也没问题。既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。比如当平均负载为 2 时,意味着什么呢?在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。
负载查看方法:
w:查看能查到在线信息和负载情况
uptime:能查到负载信息、
top:除了查看负载以外,还能动态查看其他很多性能信息,比如进程 cpu 使用率、内存使用信息、进程状态等
load average:1分钟负载,5分钟负载,15分钟负载
实际上,都要看。三个不同时间间隔的平均值,其实给我们提供了,分析系统负载趋势的数据来源,让我们能更全面、更立体地理解目前的负载状况。打个比方,就像初秋时北京的天气,如果只看中午的温度,你可能以为还在 7 月份的大夏天呢。但如果你结合了早上、中午、晚上三个时间点的温度来看,基本就可以全方位了解这一天的天气情况了。同样的,前面说到的 CPU 的三个负载时间段也是这个道理。
[root@k8sm01 ~]# w 10:59:03 up 1 min, 1 user, load average: 0.94, 0.48, 0.18 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 10.0.2.218 10:58 7.00s 0.04s 0.00s w ———————————————————————————————— [root@k8sm01 ~]# uptime 10:59:12 up 1 min, 1 user, load average: 0.80, 0.46, 0.18 ———————————————————————————————— [root@k8sm01 ~]# top top - 10:59:26 up 1 min, 1 user, load average: 0.62, 0.44, 0.17 Tasks: 124 total, 1 running, 123 sleeping, 0 stopped, 0 zombie %Cpu(s): 3.1 us, 0.0 sy, 0.0 ni, 96.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 3861372 total, 3217472 free, 250288 used, 393612 buff/cache KiB Swap: 0 total, 0 free, 0 used. 3378012 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 126132 4588 2580 S 0.0 0.1 0:03.03 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
合理负载判定:
个人认为,只要不要超过标准负载的70%就可以说明我们服务器是正常的,比如负载=N。CPU个数=C。通过以下公式得到你的负载处于什么阶段:
0<N/C*100%<50%<C :说明CPU负载比较低 0<50%<N/C*100%<100%<=C :说明CPU负载比较合理 C<N/C*100%<170%: 说明CPU负载很忙,已经出现任务等待现象 C<N/C*100%<200%: 说明CPU负载非常严重,等待现场加剧 C<200%<N/C*100%: CPU严重超负荷,有可能导致部分服务不可用,或者服务器重启事件;
另一种判定
如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了。这里我再举个例子,假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。
CPU个数查看方法:
[root@k8sm01 ~]# grep 'model name' /proc/cpuinfo | wc -l 2
平均负载与 CPU 使用率
现实工作中,我们经常容易把平均负载和 CPU 使用率混淆,所以在这里,可能你会疑惑,既然平均负载代表的是活跃进程数,那平均负载高了,不就意味着 CPU 使用率高吗?我们还是要回到平均负载的含义上来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。
所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。 • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的; • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高; • 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
基于负载案列分析:
我的按分析机器信息如下
[root@k8sm01 ~]# echo "操作系统: `cat /etc/redhat-release`" ;echo "CPU 个数: `grep 'model name' /proc/cpuinfo | wc -l`";echo -e "硬盘信息如下: \n`df -hP`";echo -e "内存信息如下: \n`free -m` " ------------------以上是执行的命令,以下是获得的结果-------------------------------------------------------------------------- 操作系统: CentOS Linux release 7.7.1908 (Core) CPU 个数: 2 硬盘信息如下: 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.9G 0 1.9G 0% /dev/shm tmpfs 1.9G 12M 1.9G 1% /run tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/mapper/centos-root 27G 2.9G 25G 11% / /dev/sda1 1014M 153M 862M 15% /boot tmpfs 378M 0 378M 0% /run/user/0 内存信息如下: total used free shared buff/cache available Mem: 3770 271 3083 11 415 3261 Swap: 0 0 0
使用到的分析工具包stress 和 sysstat
stress :是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
sysstat: 包含了常用的 Linux 性能工具iostat vmstat mpstat pidstat,用来监控和分析系统的性能。我们的案例会用到这个包的两个命令 mpstat 和 pidstat。
安装以上两个工具,如果是ubuntu apt install stress sysstat
[root@k8sm01 ~]# yum -y install stress sysstat
安装完成后开启三个终端TTY1 TTY2 TTY3
基于CPU 密集型进程分析:
TTY1:执行 taskset -c 1 stress --cpu 1 --timeout 600
[root@k8sm01 ~]# taskset -c 1 stress --cpu 1 --timeout 600

命令解释:
-n,显示已完成的指令情况 -t,运行N秒后停止 --backoff,等待N微秒后开始运行 -c,模拟N个CPU密集型进程(进程主要调用sqrt()函数计算随机数的平方根) -i,模拟N个I/O密集型进程(进程调用sync()将内存缓冲刷新到磁盘上) -m,模拟N个内存压力测试进程,进程不断调用malloc/free --vm-bytes,指定上述产生进程的malloc的大小,默认256M --vm-stride ,这项没懂? --vm-hang ,表示分配的内存经过N秒再释放 --vm-keep,保持分配的内存,不释放或者重新分配 -d,模拟N个进程做write/unlink操作 --hdd-bytes,指定硬盘写操作的进程写的文件大小 --hdd-noclean,写入的文件不删除
TTY2:执行watch -d uptime
[root@k8sm01 ~]# watch -d uptime

发现当前CPU一分以内都是接近于1
TTY3:执行mpstat -P ALL 5
[root@k8sm01 ~]# mpstat -P ALL 5 15时03分10秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 15时03分15秒 all 49.75 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 50.05 15时03分15秒 0 0.20 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.60 15时03分15秒 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

从终端二中可以看到,1 分钟的平均负载会慢慢增加到 1.00,而从终端三中还可以看到,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。
那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?你可以新建一个终端使用 pidstat或者来查询:
[root@k8sm01 ~]# pidstat -u 2 3 #每两秒刷新 共3组数据 15时10分44秒 UID PID %usr %system %guest %CPU CPU Command 15时10分46秒 0 1254 0.00 0.50 0.00 0.50 0 vmtoolsd 15时10分46秒 0 24078 99.50 0.00 0.00 99.50 1 stress 15时10分46秒 0 24368 0.00 0.50 0.00 0.50 0 pidstat 15时10分46秒 UID PID %usr %system %guest %CPU CPU Command 15时10分48秒 0 1254 0.50 0.00 0.00 0.50 0 vmtoolsd 15时10分48秒 0 24078 100.00 0.00 0.00 100.00 1 stress 15时10分48秒 0 24368 0.50 0.50 0.00 1.00 0 pidstat 15时10分48秒 UID PID %usr %system %guest %CPU CPU Command 15时10分50秒 0 476 0.00 0.50 0.00 0.50 0 xfsaild/dm-0 15时10分50秒 0 557 0.50 0.00 0.00 0.50 0 systemd-journal 15时10分50秒 0 1548 0.50 0.00 0.00 0.50 0 containerd 15时10分50秒 0 19493 0.00 0.50 0.00 0.50 0 sshd 15时10分50秒 0 24078 100.00 0.00 0.00 100.00 1 stress 平均时间: UID PID %usr %system %guest %CPU CPU Command 平均时间: 0 476 0.00 0.17 0.00 0.17 - xfsaild/dm-0 平均时间: 0 557 0.17 0.00 0.00 0.17 - systemd-journal 平均时间: 0 1254 0.17 0.17 0.00 0.33 - vmtoolsd 平均时间: 0 1548 0.17 0.00 0.00 0.17 - containerd 平均时间: 0 19493 0.00 0.17 0.00 0.17 - sshd 平均时间: 0 24078 99.83 0.00 0.00 99.83 - stress 平均时间: 0 24368 0.17 0.33 0.00 0.50 - pidstat
发现stress使用率占用了100%
通过top (输入top 在按下大P-cpu使用率排序)
[root@k8sm01 ~]# top

I/O 密集型进程
首先还是运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync:
TTY1:
[root@k8sm01 ~]# taskset -c 1 stress -i 1 --timeout 600
TTY2:
[root@k8sm01 ~]# watch -d uptime

TTY3:
[root@k8sm01 ~]# mpstat -P ALL 5 Linux 3.10.0-1062.el7.x86_64 (k8sm01.com) 2020年06月20日 _x86_64_ (2 CPU) 16时46分57秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 16时47分02秒 all 0.11 0.00 30.17 0.00 0.00 0.00 0.00 0.00 0.00 69.72 16时47分02秒 0 0.00 0.00 22.47 0.00 0.00 0.00 0.00 0.00 0.00 77.53 16时47分02秒 1 0.22 0.00 37.92 0.00 0.00 0.00 0.00 0.00 0.00 61.86 16时47分02秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 16时47分07秒 all 1.10 0.00 31.35 0.11 0.00 0.11 0.00 0.00 0.00 67.33 16时47分07秒 0 1.97 0.00 23.41 0.00 0.00 0.22 0.00 0.00 0.00 74.40 16时47分07秒 1 0.22 0.00 39.21 0.22 0.00 0.22 0.00 0.00 0.00 60.13 平均时间: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 平均时间: all 0.61 0.00 30.76 0.06 0.00 0.06 0.00 0.00 0.00 68.52 平均时间: 0 0.99 0.00 22.94 0.00 0.00 0.11 0.00 0.00 0.00 75.96 平均时间: 1 0.22 0.00 38.56 0.11 0.00 0.11 0.00 0.00 0.00 60.99

从这里可以看到,1 分钟的平均负载会慢慢增加到 1.21,指定的CPU 的系统 CPU 使用率升高到了 38.56%,可能是我的本地盘是SSD,所以没出现iowait .但是发现idle time剩余60.99%
那么到底是哪个进程,导致 系统CPU使用率这么高呢?我们还是用 pidstat 来查询
[root@k8sm01 ~]# pidstat -u 5 1 Linux 3.10.0-1062.el7.x86_64 (k8sm01.com) 2020年06月20日 _x86_64_ (2 CPU) 16时52分40秒 UID PID %usr %system %guest %CPU CPU Command 16时52分45秒 0 9 0.00 0.20 0.00 0.20 1 rcu_sched 16时52分45秒 0 477 0.00 0.20 0.00 0.20 0 kworker/0:1H 16时52分45秒 0 1548 0.20 0.20 0.00 0.40 0 containerd 16时52分45秒 0 37224 0.00 29.34 0.00 29.34 0 kworker/u256:1 16时52分45秒 0 38831 0.20 75.45 0.00 75.65 1 stress 16时52分45秒 0 38832 0.00 33.13 0.00 33.13 0 kworker/u256:0 16时52分45秒 0 38871 0.00 0.20 0.00 0.20 1 pidstat 平均时间: UID PID %usr %system %guest %CPU CPU Command 平均时间: 0 9 0.00 0.20 0.00 0.20 - rcu_sched 平均时间: 0 477 0.00 0.20 0.00 0.20 - kworker/0:1H 平均时间: 0 1548 0.20 0.20 0.00 0.40 - containerd 平均时间: 0 37224 0.00 29.34 0.00 29.34 - kworker/u256:1 平均时间: 0 38831 0.20 75.45 0.00 75.65 - stress 平均时间: 0 38832 0.00 33.13 0.00 33.13 - kworker/u256:0 平均时间: 0 38871 0.00 0.20 0.00 0.20 - pidstat

可以发现,还是 stress 进程导致的。
基于大量进程的场景
当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。比如,我们还是使用 stress,但这次模拟的是 >=4个进程:
[root@k8sm01 ~]# stress -c 4 --timeout 600 [root@k8sm01 ~]# watch -d uptime

负载会维持在4左右
查看CPU使用情况
[root@k8sm01 ~]# mpstat -P ALL 5

2个CPU都已经跑满了
[root@k8sm01 ~]# pidstat -u 5

查看是由于4个 stress进程导致