当系统变慢时 我们会看系统的平均负载
[root@localhost ~]# uptime 04:05:02 up 1 min, 2 users, load average: 0.44, 0.19, 0.07
04:05:02 // 当前时间 up 1 min // 系统运行时间 2 user // 正在登录用户数 0.44,0.19,0.07 //系统1分钟,5分钟15分钟的平均负载
平均负载是指系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。其和cpu使用率不一定一致,也可以说没有直接关系。
可运行状态进程是指正在使用cpu或者正在等待cpu的进程,也就是ps aux命令看到的处于R状态的进程
不可中断状态的进程是处于内核态关键流程中的进程,且这些进程是不可打断的。比如等待硬件设备的i/o响应。也就是ps命令看到的D状态
如一个进程向硬盘读写数据时,为了保证数据的一致性,在得到硬盘回复前 是不能被其他进程中断的,否则会造成磁盘数据与进程数据不一致的问题
所以 不可中断状态是系统对进程和硬件设备的一种保护机制
既然平均的是活跃进程数,那理想状态是每个cpu正好运行一个进程,这样每个cpu都得到了充分利用。
假如 当前平均负载是2 这意味什么呢?
在2个cpu的系统上,意味着所有cpu都刚好被完全占用
在4个cpu的系统上,意味着cpu有50%的空闲
而在1个cpu的系统上 ,则意味着有一半的进程在排队 竞争不到cpu
那么平均负载最理想情况是等于cpu的个数。
查看cpu个数
[root@localhost ~]# grep 'model name' /proc/cpuinfo |wc -l 2
1分钟 5分钟 15分钟的平均负载 提供给我们一个cpu平均负载的使用趋势
如果1分钟的值远小于15分钟的值 说明系统最近1分行的负载在减少,而过去15分钟内却有很大的负载
反过来如果1分钟的值远大于15分钟,说明最近1分钟的负载在增加,这种增加有可能只是临时性的,也可能会持续增加下去,所以就需要持续观察
如果一分钟的平均负载接近或超过cpu个数,就意味着系统正在发生过载问题,要想办法优化了。
在生产环境中 平均负载高于cpu数量70%的时候,就应该分析排查负载高的问题了。负载过高可能导致进程响应变慢,进而影响服务正常功能。
但这个数字只是估数,要结合监控,结合历史数据 业务场景判断负载的变化趋势。
平均负载与cpu使用率
在实际工作中,我们经常容易把平均负载和cpu使用率混淆。
平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数,所以,它不仅包括正在使用的cpu进程,还包括等待cpu和等待i/o的进程
cpu使用率是单位时间内cpu工作情况的统计。跟平均负载不一定完全对应。比如:
cpu密集型进程,使用大量cpu导致平均负载升高,此时两者是一致的;
I/O密集型进程,等待I/O也会导致平均负载升高,但CPU使用率不一定很高;
大量等待CPU的进程调度也会导致平均负载升高,此时的CPU使用率也会比较高
平均负载案例分析
下面用三个示例来看这三种情况,并用iostat,mpstat,pidstat等工具,找出平均负载升高的根源
机器配置:2CPU,8GB内存
预先安装strees和sysstat包
stress 是一个linux系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
sysstat包含了常用的linux性能工具,用来监控和分析系统的性能。案例中会用到这个包的mpstat 和pidstat命令
mpstat是一个多核cpu性能分析工具,用来实时查看每个cpu的性能指标,以及所有cpu的平均指标
pidstat是一个常用的进程性能分析工具,用来实时查看进程的cpu,内存,I/O以及上下文切换等性能指标
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum install stress sysstat -y
实验前先用uptime查看测试前的平均负载情况
[root@localhost ~]# uptime 05:14:49 up 1:10, 2 users, load average: 0.11, 0.15, 0.09
场景一:cpu密集型进程
首先用stress模拟cpu使用率100%的场景
终端1 模拟cpu使用率100%
[root@localhost yum.repos.d]# stress --cpu 1 --timeout 600
终端2 运行uptime 查看平均负载变化情况 能够看到 1分钟平均cpu负载慢慢涨到了1
[root@localhost ~]# watch -d uptime
..., load average: 1.00, 0.75...
终端3 用mpstat查看cpu使用率变化
可以看到一个cpu的使用率为100%,它的iowait只有0,这说明 平均负载的升高正是由于cpu使用率为100%
[root@localhost ~]# mpstat -P ALL 5 Linux 3.10.0-693.el7.x86_64 (localhost) 03/11/2019 _x86_64_ (1 CPU) 05:35:13 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 05:35:18 AM all 100.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 05:35:18 AM 0 100.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
用pidstat 查看哪个进程的cpu使用率占到了100%
[root@localhost ~]# pidstat -u 5
05:48:28 AM UID PID %usr %system %guest %CPU CPU Command 05:48:33 AM 0 2010 100.00 0.00 0.00 100.00 0 stress 05:48:33 AM 0 2012 0.00 0.20 0.00 0.20 0 pidstat
从这里就能看出stress的cpu使用率为100%
场景二:I/O密集型进程
第一个终端:运行stress命令,模拟I/O压力
# stress -i 1 --timeout 600
stress-ng -i 1 --hdd 1 --timeout 600 #由于stress使用的是sync()系统调用,它是刷新缓冲区内存到磁盘中,对于虚拟机缓冲区可能比较小,
无法产生打的IO压力,这样大部分就都是系统调用消耗了,只能看到cpu使用率升高,使用下一代stress-ng
第二个终端运行uptime 查看平均负载变化情况
# watch -d uptime
load average: 1.06, 0.58, 0.37
第三个终端运行mpstat 查看CPU使用率的变化情况
[root@localhost ~]# mpstat -P ALL 5 10 #5秒刷新一次 10次 Linux 3.10.0-693.el7.x86_64 (localhost) 03/11/2019 _x86_64_ (1 CPU) 06:56:26 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 06:56:31 AM all 0.22 0.00 20.48 77.09 0.00 2.20 0.00 0.00 0.00 0.00 06:56:31 AM 0 0.22 0.00 20.48 77.09 0.00 2.20 0.00 0.00 0.00 0.00
可以看到1分钟的平均负载慢慢增加到1.06,其中一个cpu的系统cpu使用率到了20.48 而iowait高达77.09%。这说明平均负载的升高是由于iowait的升高
在用pidstat 查看 那个进程导致iowait高
[root@localhost ~]# pidstat -u 5 1 Linux 3.10.0-693.el7.x86_64 (localhost) 03/11/2019 _x86_64_ (1 CPU) 07:12:51 AM UID PID %usr %system %guest %CPU CPU Command 07:12:56 AM 0 3 0.00 0.22 0.00 0.22 0 ksoftirqd/0 07:12:56 AM 0 750 0.22 0.22 0.00 0.44 0 vmtoolsd 07:12:56 AM 0 3547 0.00 2.84 0.00 2.84 0 kworker/u256:0 07:12:56 AM 0 4531 0.00 1.53 0.00 1.53 0 kworker/0:1 07:12:56 AM 0 4572 0.00 23.14 0.00 23.14 0 stress-ng-hdd 07:12:56 AM 0 4573 0.00 0.44 0.00 0.44 0 stress-ng-io 07:12:56 AM 0 4652 0.00 0.44 0.00 0.44 0 pidstat
# pidstat -d .... 08:09:33 AM 0 1691 0.00 0.00 0.00 bash 08:09:33 AM 0 5090 0.00 0.01 0.00 watch 08:09:33 AM 0 5122 0.02 0.33 0.02 bash 08:09:33 AM 0 7812 0.00 138.60 13.77 stress-ng-hdd
场景三 大量进程的场景
当系统中运行的进程超出CPU运行能力时,就会出现等待CPU的进程
我们用stress模拟8个进程
终端1:
[root@localhost yum.repos.d]# stress -c 8 --timeout 600
终端2:
[root@localhost ~]# uptime 07:19:37 up 3:15, 4 users, load average: 6.76, 3.75, 2.27
终端3: pidstat查看进程情况
[root@localhost ~]# pidstat -u 5 1 Linux 3.10.0-693.el7.x86_64 (localhost) 03/11/2019 _x86_64_ (1 CPU) 07:22:24 AM UID PID %usr %system %guest %CPU CPU Command 07:22:29 AM 0 4978 12.55 0.00 0.00 12.55 0 stress 07:22:29 AM 0 4979 12.35 0.00 0.00 12.35 0 stress 07:22:29 AM 0 4980 12.55 0.00 0.00 12.55 0 stress 07:22:29 AM 0 4981 12.35 0.00 0.00 12.35 0 stress 07:22:29 AM 0 4982 12.55 0.00 0.00 12.55 0 stress 07:22:29 AM 0 4983 12.55 0.00 0.00 12.55 0 stress 07:22:29 AM 0 4984 12.35 0.00 0.00 12.35 0 stress 07:22:29 AM 0 4985 12.35 0.00 0.00 12.35 0 stress
其他好用的定位工具如htop atop