一、怎样理解“平均负载”?
每次发现系统变慢时,我们通常做的第一件事,就是执行top或者uptime命令,来了解系统的负载情况。比如:
$uptime
14:10:30 up 161 days, 4:10, 1 user, load average: 0.63, 0.83, 0.88
每一列输出的含义:
14:10:30 //当前时间
up 161 days, 4:10 //系统运行时间
1 user // 正在登陆的用户数
1.平均负载
而最后三个数字呢,依次则是过去1分钟、5分钟、15分钟的平均负载。
我猜一定有人会说,平均负载不就是单位时间内的CPU使用率吗?上面的0.63,就代表CPU使用率是63%。其实并不是这样,可以通过执行man uptime命令来了解平均负载的详细解释。
简单来说,平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和cpu使用率没有直接关系。
可运行状态:是指正在使用cpu或者正在等待cpu的进程,也就是我们常用ps命令看到的,处于R状态(Running或者Runnable)的进程
不可中断状态:正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如常见的是等待硬件设备的I/O相应,也就是我们在
ps命令中看到的D状态(Uninterruptible Sleep,也称为Disk Sleep)的进程。这个时候的 进程处于不可终端状态,
如果此时的进程被打断了 ,就容易出现磁盘数据与进程不一致的问题
所以,不可中断状态实际上是系统对进程和硬件的一种保护机制
2.当平均负载2时,意味着什么呢
既然是平均的活跃进程数,那么最理想的,就是每个cpu上都刚好运行着一个进程,这样每个cpu都得到了充分利用,比如当平均负载2时,意味着什么呢?
1、在只有2个CPU的系统上,意味着所有的CPU都刚好被完全占用
2、在4个CPU的系统上,意味着CPU有50%的空闲
3、而在只有1个CPU的系统上,则意味着有一半的进程竞争不到CPU
二、平均负载为多少时合理
平均负载最理想的情况等于CPU的个数
1、系统有几个CPU?
首先你要知道系统有几个cpu,这可以通过top命令或者从文件/proc/cpuinfo中读取,比如:
# 关于 grep 和 wc 的用法请查询它们的手册或者网络搜索
$grep 'model name' /proc/cpuinfo |wc -l
8
当平均负载高于 CPU 数量 70% 排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。但70%这个数字并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显升高趋势时,比如负载翻倍了,你再去做分析和调查。
三、平均负载与 CPU 使用率
现实工作中,我们经常容易把平均负载和CPU使用率混淆,我们做个区分。
平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所有,它不仅包含了正在使用 CPU 的进程,还包括等待 CPU和等待 I/O 的进程。
而CPU使用率,是单位时间内CPU繁忙情况的 统计,跟平均负载并不一定完全对应。 比如:
1、CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者一直的
2、I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
3、大量等待 CPU 的进程调度也会导致平均负载升高,此时的CPU 使用率也会比较高
四、实战
1、环境与测试工具
1、操作系统
[root@ensp-nginx ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
2、测试工具
yum install stress-ng sysstat -y
升级sysstat版本到11.5以上
rpm -qa|grep sysstat
wget http://www.rpmfind.net/linux/opensuse/tumbleweed/repo/oss/x86_64/sysstat-12.6.2-4.2.x86_64.rpm
rpm -Uvh sysstat-12.6.2-4.2.x86_64.rpm
rpm -qa|grep sysstat
stress-ng和stress都是用于在计算机系统上进行压力测试和性能测试的工具。它们可以模拟 CPU、内存、磁盘和I/O 等方面的负载,以便评估系统在高负荷下的稳定性和表现。stress是一个比较常见的压力测试工具,而stress-ng则是其进化版,提供了更多的压力测试选项和功能。两者都可以帮助系统管理员和开发人员发现系统中的潜在问题,并优化系统性能。
2、场景一:CPU 密集型进程
首先,我们在第一个终端运行stress-ng命令,模拟一个CPU使用率100%的场景:
stress-ng --cpu 1 --timeout 600
接着,在第二个终端运行uptime查看平均负载情况:
#-d参数表示高亮显示变化的区域
watch -d uptime
#1 分钟的平均负载会慢慢增加到 1.00
最后,在第三个终端运行mpstat查看CPU使用率的变化情况:
# -P ALL 表示监控所有CPU,后面的数字5表示间隔5秒输出一组数据
# mpstat -P ALL 5
Linux 3.10.0-1160.92.1.el7.x86_64 (ensp-nginx) 04/08/2024 _x86_64_ (8 CPU)
03:26:51 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:26:56 PM all 13.18 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.00 86.77
03:26:56 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
03:26:56 PM 1 0.20 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.60
03:26:56 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
03:26:56 PM 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:26:56 PM 4 0.20 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.60
03:26:56 PM 5 5.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 94.80
03:26:56 PM 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
03:26:56 PM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
从终端二中可以看到,1分钟的平均负载会慢慢增加到1.00,而从终端三中可以看到,正好有一个CPU的使用率为100%,但它的iowait只有0.这说明,平均负载的升高正是由于CPU使用率为100%。
那么,到底是哪个进程导致了CPU使用率为100%呢?你可以使用pidstat来查询:
# 间隔5秒后输出一组数据 -u表四cpu指标
pidstat -u 5 1
Linux 3.10.0-1160.92.1.el7.x86_64 (ensp-nginx) 04/08/2024 _x86_64_ (8 CPU)
03:36:41 PM UID PID %usr %system %guest %CPU CPU Command
03:36:46 PM 0 981 5.60 0.20 0.00 5.80 6 hostguard
03:36:46 PM 0 9441 100.00 0.00 0.00 100.00 1 stress-ng-cpu
03:36:46 PM 0 23729 0.20 0.00 0.00 0.20 4 uniagentd
Average: UID PID %usr %system %guest %CPU CPU Command
Average: 0 981 5.60 0.20 0.00 5.80 - hostguard
Average: 0 9441 100.00 0.00 0.00 100.00 - stress-ng-cpu
Average: 0 23729 0.20 0.00 0.00 0.20 - uniagentd
从这里可以明显看到,stress-ng进程的CPU使用率为100%。
3、场景二:I/O 密集型进程
首先还是运行stress命令,但这次模拟I/O压力
stress-ng -i 1 --hdd 1 --timeout 600
还是在第二个终端运行uptime查看平均负载变化情况:
watch -d uptime
..., load average: 3.85, 2.21, 0.98
然后,第三个终端运行mpstat查看CPU使用率的情况:
#显示所有cpu的指标,并在间隔5秒输出一组数据
mpstat -P ALL 5 1
Linux 3.10.0-1160.92.1.el7.x86_64 (ensp-nginx) 04/08/2024 _x86_64_ (8 CPU)
04:36:44 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
04:36:49 PM all 0.68 0.00 3.00 41.20 0.00 0.05 0.00 0.00 0.00 55.07
04:36:49 PM 0 1.21 0.00 1.01 55.53 0.00 0.00 0.00 0.00 0.00 42.25
04:36:49 PM 1 0.20 0.00 0.20 0.20 0.00 0.00 0.00 0.00 0.00 99.40
04:36:49 PM 2 1.20 0.00 16.23 51.30 0.00 0.60 0.00 0.00 0.00 30.66
04:36:49 PM 3 1.40 0.00 0.20 19.24 0.00 0.00 0.00 0.00 0.00 79.16
04:36:49 PM 4 0.00 0.00 1.80 95.21 0.00 0.00 0.00 0.00 0.00 2.99
04:36:49 PM 5 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.80
04:36:49 PM 6 0.20 0.00 3.61 59.52 0.00 0.00 0.00 0.00 0.00 36.67
04:36:49 PM 7 1.20 0.00 0.60 48.60 0.00 0.00 0.00 0.00 0.00 49.60
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 0.68 0.00 3.00 41.20 0.00 0.05 0.00 0.00 0.00 55.07
Average: 0 1.21 0.00 1.01 55.53 0.00 0.00 0.00 0.00 0.00 42.25
Average: 1 0.20 0.00 0.20 0.20 0.00 0.00 0.00 0.00 0.00 99.40
Average: 2 1.20 0.00 16.23 51.30 0.00 0.60 0.00 0.00 0.00 30.66
Average: 3 1.40 0.00 0.20 19.24 0.00 0.00 0.00 0.00 0.00 79.16
Average: 4 0.00 0.00 1.80 95.21 0.00 0.00 0.00 0.00 0.00 2.99
Average: 5 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.80
Average: 6 0.20 0.00 3.61 59.52 0.00 0.00 0.00 0.00 0.00 36.67
Average: 7 1.20 0.00 0.60 48.60 0.00 0.00 0.00 0.00 0.00 49.60
1 分钟的平均负载会慢慢增加到 1.00
其中一个 CPU 的系统 CPU 使用率升高到了 16.23,而 iowait 高达 51.30%。这说明,平均负载的升高是由于 iowait 的升高。
那么到底是哪个进程,导致的iowait这么高呢?
# 间隔5秒后输出一组数据,-u表四cpu指标
pidstat -u 5 1
Linux 3.10.0-1160.92.1.el7.x86_64 (ensp-nginx) 04/08/2024 _x86_64_ (8 CPU)
04:40:08 PM UID PID %usr %system %guest %CPU CPU Command
04:40:13 PM 0 310 0.00 3.39 0.00 3.39 0 jbd2/vda1-8
04:40:13 PM 0 379 0.00 0.40 0.00 0.40 2 kworker/2:1H
04:40:13 PM 0 981 4.59 1.80 0.00 6.39 7 hostguard
04:40:13 PM 0 10488 0.00 1.20 0.00 1.20 4 kworker/u16:1
04:40:13 PM 0 10617 0.20 30.14 0.00 30.34 3 stress-ng-hdd
04:40:13 PM 0 10618 0.00 3.59 0.00 3.59 4 stress-ng-io
04:40:13 PM 0 10715 0.00 0.20 0.00 0.20 4 pidstat
04:40:13 PM 0 23728 0.00 0.20 0.00 0.20 6 uniagentd
Average: UID PID %usr %system %guest %CPU CPU Command
Average: 0 310 0.00 3.39 0.00 3.39 - jbd2/vda1-8
Average: 0 379 0.00 0.40 0.00 0.40 - kworker/2:1H
Average: 0 981 4.59 1.80 0.00 6.39 - hostguard
Average: 0 10488 0.00 1.20 0.00 1.20 - kworker/u16:1
Average: 0 10617 0.20 30.14 0.00 30.34 - stress-ng-hdd
Average: 0 10618 0.00 3.59 0.00 3.59 - stress-ng-io
Average: 0 10715 0.00 0.20 0.00 0.20 - pidstat
Average: 0 23728 0.00 0.20 0.00 0.20 - uniagentd
4、场景三:大量进程的场景
当系统中运行进程超出CPU运行能力时,就会出现等待CPU的进程。
比如,我们还是使用stress,但这次模拟的 是16个进程:
stress-ng -c 16 --timeout 600
由于系统只有8个CPU,明显比16个进程要少得多,因而,系统的cpu处于严重的过载状态,平均负载高达15.31:
uptime
17:28:24 up 161 days, 7:28, 2 users, load average: 15.31, 6.14, 2.47
运行pidstat来看下进程的情况:
pidstat -u 5 1
Linux 3.10.0-1160.92.1.el7.x86_64 (ensp-nginx) 04/08/2024 _x86_64_ (8 CPU)
05:31:51 PM UID PID %usr %system %guest %CPU CPU Command
05:31:56 PM 0 981 4.99 0.00 0.00 4.99 2 hostguard
05:31:56 PM 0 11729 24.95 0.00 0.00 24.95 5 stress-ng-cpu
05:31:56 PM 0 11730 24.95 0.00 0.00 24.95 0 stress-ng-cpu
05:31:56 PM 0 11731 24.95 0.00 0.00 24.95 3 stress-ng-cpu
05:31:56 PM 0 11732 24.75 0.00 0.00 24.75 0 stress-ng-cpu
05:31:56 PM 0 11733 24.95 0.00 0.00 24.95 4 stress-ng-cpu
05:31:56 PM 0 11734 24.75 0.00 0.00 24.75 6 stress-ng-cpu
05:31:56 PM 0 11735 24.75 0.00 0.00 24.75 6 stress-ng-cpu
05:31:56 PM 0 11736 25.15 0.00 0.00 25.15 2 stress-ng-cpu
05:31:56 PM 0 11737 25.15 0.00 0.00 25.15 4 stress-ng-cpu
05:31:56 PM 0 11738 25.15 0.00 0.00 25.15 0 stress-ng-cpu
05:31:56 PM 0 11739 25.15 0.00 0.00 25.15 3 stress-ng-cpu
05:31:56 PM 0 11740 25.15 0.00 0.00 25.15 5 stress-ng-cpu
05:31:56 PM 0 11741 24.15 0.00 0.00 24.15 7 stress-ng-cpu
05:31:56 PM 0 11742 24.95 0.00 0.00 24.95 1 stress-ng-cpu
05:31:56 PM 0 11743 24.95 0.00 0.00 24.95 4 stress-ng-cpu
05:31:56 PM 0 11744 24.15 0.00 0.00 24.15 7 stress-ng-cpu
05:31:56 PM 0 11745 24.95 0.00 0.00 24.95 1 stress-ng-cpu
05:31:56 PM 0 11746 24.55 0.00 0.00 24.55 2 stress-ng-cpu
05:31:56 PM 0 11747 24.15 0.00 0.00 24.15 7 stress-ng-cpu
05:31:56 PM 0 11748 24.95 0.00 0.00 24.95 1 stress-ng-cpu
05:31:56 PM 0 11749 24.55 0.00 0.00 24.55 3 stress-ng-cpu
05:31:56 PM 0 11750 24.95 0.00 0.00 24.95 5 stress-ng-cpu
05:31:56 PM 0 11751 24.55 0.00 0.00 24.55 6 stress-ng-cpu
05:31:56 PM 0 11752 24.95 0.00 0.00 24.95 3 stress-ng-cpu
05:31:56 PM 0 11753 23.95 0.00 0.00 23.95 7 stress-ng-cpu
05:31:56 PM 0 11754 24.95 0.00 0.00 24.95 5 stress-ng-cpu
05:31:56 PM 0 11755 24.95 0.00 0.00 24.95 1 stress-ng-cpu
05:31:56 PM 0 11757 25.15 0.00 0.00 25.15 2 stress-ng-cpu
05:31:56 PM 0 11758 24.75 0.00 0.00 24.75 6 stress-ng-cpu
05:31:56 PM 0 11759 24.75 0.00 0.00 24.75 4 stress-ng-cpu
05:31:56 PM 0 11760 24.75 0.00 0.00 24.75 0 stress-ng-cpu
05:31:56 PM 0 11761 25.35 0.00 0.00 25.35 2 stress-ng-cpu
Average: UID PID %usr %system %guest %CPU CPU Command
Average: 0 981 4.99 0.00 0.00 4.99 - hostguard
Average: 0 11729 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11730 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11731 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11732 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11733 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11734 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11735 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11736 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11737 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11738 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11739 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11740 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11741 24.15 0.00 0.00 24.15 - stress-ng-cpu
Average: 0 11742 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11743 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11744 24.15 0.00 0.00 24.15 - stress-ng-cpu
Average: 0 11745 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11746 24.55 0.00 0.00 24.55 - stress-ng-cpu
Average: 0 11747 24.15 0.00 0.00 24.15 - stress-ng-cpu
Average: 0 11748 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11749 24.55 0.00 0.00 24.55 - stress-ng-cpu
Average: 0 11750 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11751 24.55 0.00 0.00 24.55 - stress-ng-cpu
Average: 0 11752 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11753 23.95 0.00 0.00 23.95 - stress-ng-cpu
Average: 0 11754 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11755 24.95 0.00 0.00 24.95 - stress-ng-cpu
Average: 0 11757 25.15 0.00 0.00 25.15 - stress-ng-cpu
Average: 0 11758 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11759 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11760 24.75 0.00 0.00 24.75 - stress-ng-cpu
Average: 0 11761 25.35 0.00 0.00 25.35 - stress-ng-cpu
小结
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:
1、平均负载高有可能是 CPU 密集型进程导致的;
2、平均负载负载高并不一定代表 CPU 使用率高,还有可能是 I/O I/O 更繁忙了
3、当发现负载高的时候,你可以使用 mpstat、pidstat等工具,辅助分析负载的来源
stress参数
stress参数
表1 stress参数
参数 功能
-?,–help 显示帮助信息
–version 显示版本信息
-v,–verbose 运行时显示详细的信息
-q,–quiet 运行时不显示运行信息
-n,–dry-run 显示以完成的指令情况
-t,–timeout 指定程序运行结束的时间,单位为秒
–backoff 指定程序开始运行的时间,单位为微妙
-c,–cpu 后面跟一个整数,表示测试CPU的进程数-c 2 :表示生成2个worker循环调用sqrt()产生cpu压力
-i,–io 后面跟一个整数,表示测试磁盘I/O的进程数-i 1 :表示生成1个worker循环调用sync()产生io压力
-m,–vm 后面跟一个整数,表示测试内存的进程数-m 1 :表示生成1个worker循环调用malloc()/free()产生内存压力
–vm-bytes 指定在内存测试时malloc的字节数,默认256M
–vm-stride 指定每B个字节移动一个字节
–vm-hang 指定free栈的秒数
–vm-keep 向内存空间内不断写入,而不是释放和重新分配
-d,–hdd 产生执行write和unlink函数的进程数
–hdd-bytes 指定写的字节数
stress-ng参数
stress-ng参数有几百项,可以模拟复杂的压力测试,但是兼容stress的参数。 主要使用参数:
参数 功能
-c N 运行N worker CPU压力测试进程
--cpu-method all worker从迭代使用30多种不同的压力算法,包括pi, crc16, fft等等
-tastset N 将压力加到指定核心上
-d N 运行N worker HDD write/unlink测试
-i N 运行N worker IO测试