学习倪鹏飞老师linux性能优化实践的笔记,文中大量内容来源于老师的文档材料,如果喜欢请移步文末截图中的二维码支持老师的课程:
一般在我们发现系统有问题的时候,大家的第一反应肯定都是看下当前的CPU使用状态,看下当前的内存使用状态,看下当前的磁盘使用状态。那么不可避免的大家肯定会使用top
这个命令,那么我们今天看下top中的load值是如何计算的。
首先,我们简单的理解下这个指标
load average: 0.00, 0.01, 0.05
load average 有3个指标,分别是,1分钟平均负载、5分钟平均负载、15分钟平均负载 ,我们可以根据这三个指标,看到我们当前的系统负载整体是下降的,还是上升的。
好,理解了3个指标的含义后,我们来看下这3个指标是如何计算的。
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,他和CPI使用率并没有直接的关系,那么可运行状态和不可中断状态怎么理解呢?
可运行状态:指正在使用CPU或者正在等待CPU的进程,也就是我们常用ps aux
命令看到的处于R(running,runnable)状态的进程。
不可中断状态:指进程正处于内核态关键流程中的进程,并且这些流程是不可被打断的,比如最长久的是等待硬件设备的I/O响应,也就是我们在ps aux
命令中看到的D(Uniterruptible,Disk Sleep)状态的进程。
比如,当一个进程向磁盘写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态,如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。
所以,不可中断状态,实际上是系统对进程和硬件设备的一种保护机制。
因此,你可以简单的理解为,平均负载其实就是平均活跃进程数,平均活跃进程数,直观上的理解就是单位时间内的活跃进程数。但他实际上是活跃进程数的指数衰减平均值。这“指数衰减平均”可以不用计较,只是一种更快速的计算方式,你可以把它直接当成活跃进程数的平均值即可。
既然平均的是活跃进程数,那么最理想的就是每个CPU上刚好运行着一个进程,这样每个CPU都得到了充分的利用,比如当平均负载为2时,意味着什么呢?
- CPU核心数,指逻辑CPU,即一个CPU不开超线程时为2个物理核心,开了超线程后就变成了4个逻辑核心。
- 在只有2个CPU核心的系统上,意味着所有CPU核心数都刚好被完全占用。
- 在有4个CPU核心的系统上,意味着CPU有50%的空闲。
- 而在只有2个CPU核心的系统中,则意味着有一半的进程竞争不到CPU。
平均负载多少时合理?
在评估这个值的时候,首先我们要看下当前有多少个逻辑CPU,一般我们直接看/proc/cpuinfo
的数据即可
[root@localhost ~]# cat /proc/cpuinfo |grep "model name"|wc -l
16
那么比如我这台机器,看到的就是16个逻辑核心了。
有了CPU个数,我们就可以判断出,当平均负载比CPU个数还大的时候,系统已经出现了过载。
不过这个观察也是要评估多个指标的,我们要同时用1分钟5分钟15分钟的值来大概的估算这个设备的负载是呈现上升或者下降的趋势,其实最好的方式是通过监控的手段,采集足够多的load值,这样可以更精准的知道自己设备的负载情况。
平均负载与CPU使用率
在日常使用中,我们经常容易把平均负载和CPU使用率混淆,这里我们做下区分。
可能我们会有疑惑,既然平均负载代表的是活跃进程数,那么平均负载搞了,不就意味着CPU使用率高了吗?
这里我们还得回到平均负载的含义上来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数,所以,他不仅包扩了正在使用CPU的进程,还包括等待CPU和等待I/O的进程。
而CPU使用率,是单位时间内CPU繁忙情况的统计,和平均负载并不一定完全对应。比如:
- CPU密集型进程,使用大量CPU会导致平均负载升高,此时这两者是一致的。
- I/O 密集型进程, 等待I/O也会导致平均负载升高,但是CPU使用率不一定很高。
- 大量等待CPU的进程调用也会导致平均负载升高,此时的CPU使用率也会比较高。
平均负载案例分析
这里会用到2个工具,stress和sysstat
stress是一个Linux系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
sysstat是一个linux性能工具,用来监控和分析系统的性能,以下案例中会用到这个包的2个命令mpstat和pidstat。
- mpstat 是一个常用的多核CPU性能分析工具用来实时查看每个CPU的性能指标,一级所有CPI的平均指标。
- pidstat 是一个常用的进程性能分析工具,用来实时查看进程的CPU、内存、I/O以及上下文切换等性能指标。
场景1:CPU密集型进程
我们打开终端一运行stree命令,模拟一个CPU使用率100%的场景:
[root@localhost ~]# stress --cpu 1 --timeout 600
stress: info: [5399] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
我们打开终端二,查看CPU负载的上升状态
[root@localhost ~]# uptime
01:50:42 up 1 day, 1:42, 3 users, load average: 0.68, 0.22, 0.11
[root@localhost ~]# uptime
01:50:45 up 1 day, 1:42, 3 users, load average: 0.71, 0.23, 0.12
[root@localhost ~]# uptime
01:51:10 up 1 day, 1:43, 3 users, load average: 0.81, 0.29, 0.14
[root@localhost ~]# uptime
01:54:58 up 1 day, 1:47, 4 users, load average: 1.03, 0.68, 0.33
一段时间后,我们发现1分钟的平均load值超过了1,为啥? 设备上还有些其他进程运行啊。
打开终端三,查看CPU使用状态
[root@localhost ~]# mpstat -P ALL 5
Linux 3.10.0-514.16.1.el7.x86_64 (localhost.localdomain) 11/24/2018 _x86_64_ (16 CPU)
01:53:08 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
01:53:13 AM all 6.24 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 93.73
01:53:13 AM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.20 0.00 0.00 99.80
01:53:13 AM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 2 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.80
01:53:13 AM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 4 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.80
01:53:13 AM 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 6 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.80
01:53:13 AM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 8 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.80
01:53:13 AM 9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
01:53:13 AM 15 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
这里我们可以看到,在CPU15上 CPU的使用率一直处于100%状态,使用这个工具可以持续看到状态的变化。
从终端二中可以看到,1分钟的平均负载慢慢会增加到1,而从终端三中可以看到,正好有一个CPU的使用率为100%,但他的iowait为0,这说明,平均负载的升高正是由于CPU使用率为100%。
那么,到底是哪个进程导致了CPU使用率为100%呢? 你可以使用pidstat来查询:
[root@localhost ~]# pidstat -u 5 1
Linux 3.10.0-514.16.1.el7.x86_64 (localhost.localdomain) 11/24/2018 _x86_64_ (16 CPU)
02:00:20 AM UID PID %usr %system %guest %CPU CPU Command
02:00:25 AM 0 8451 100.00 0.00 0.00 100.00 2 stress
02:00:25 AM 0 8456 0.00 0.20 0.00 0.20 3 pidstat
02:00:25 AM 0 8457 0.20 0.20 0.00 0.40 15 client
Average: UID PID %usr %system %guest %CPU CPU Command
Average: 0 8451 100.00 0.00 0.00 100.00 - stress
Average: 0 8456 0.00 0.20 0.00 0.20 - pidstat
Average: 0 8457 0.20 0.20 0.00 0.40 - client
从这里,可以明显看到,stress进程的CPU使用率为100%。
场景二:I/O 密集型进程
首先还是运行stress命令,但这次模拟I/O压力,即不停的执行sync:
打开终端一,执行stress
[root@localhost ~]# stress -i 1 --timeout 3600
stress: info: [8817] dispatching hogs: 0 cpu, 1 io, 0 vm, 0 hdd
打开终端二
[root@localhost ~]# uptime
02:02:36 up 1 day, 1:54, 4 users, load average: 0.83, 0.85, 0.56
[root@localhost ~]# uptime
02:05:27 up 1 day, 1:57, 4 users, load average: 0.99, 0.92, 0.63
这里,也会看到,load会不断的升高
打开终端三
[root@localhost ~]# mpstat -P ALL 5
Linux 3.10.0-514.16.1.el7.x86_64 (localhost.localdomain) 11/24/2018 _x86_64_ (16 CPU)
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 0.05 0.00 5.93 0.34 0.00 0.00 0.05 0.00 0.00 93.63
Average: 0 0.16 0.00 0.48 0.00 0.00 0.00 0.14 0.00 0.00 99.22
Average: 1 0.03 0.00 0.09 0.01 0.00 0.00 0.03 0.00 0.00 99.84
Average: 2 0.03 0.00 0.09 0.00 0.00 0.00 0.01 0.00 0.00 99.88
Average: 3 0.09 0.00 0.23 0.00 0.00 0.00 0.03 0.00 0.00 99.65
Average: 4 0.13 0.00 0.53 0.00 0.00 0.00 0.05 0.00 0.00 99.29
Average: 5 0.02 0.00 0.05 0.00 0.00 0.00 0.05 0.00 0.00 99.88
Average: 6 0.02 0.00 0.35 0.00 0.00 0.00 0.08 0.00 0.00 99.56
Average: 7 0.02 0.00 0.04 0.00 0.00 0.00 0.03 0.00 0.00 99.90
Average: 8 0.02 0.00 0.14 0.00 0.00 0.00 0.04 0.00 0.00 99.80
Average: 9 0.10 0.00 0.28 0.00 0.00 0.00 0.03 0.00 0.00 99.59
Average: 10 0.09 0.00 0.34 0.00 0.00 0.00 0.05 0.00 0.00 99.52
Average: 11 0.01 0.00 0.06 0.00 0.00 0.00 0.03 0.00 0.00 99.90
Average: 12 0.03 0.00 33.73 1.96 0.00 0.00 0.05 0.00 0.00 64.23
Average: 13 0.02 0.00 0.04 0.00 0.00 0.00 0.02 0.00 0.00 99.92
Average: 14 0.03 0.00 2.43 0.12 0.00 0.00 0.04 0.00 0.00 97.37
Average: 15 0.04 0.00 56.38 3.30 0.00 0.00 0.17 0.00 0.00 40.12
这里看到,CPU的use使用不是很高,反而sys使用的比较高,分布在了2个CPU上,约等于100%
同时可以看到iowait的值也升高了一些,由于我的设备全是ssd磁盘,所以这个io的性能可能会稍微好一些。
从以上操作中,我们看到1分钟的平均负载会慢慢的增加,其中一个CPU的系统CPU使用率提升到了56,同时iowait也提升到了3,这说明平均负载的升高是由于系统资源使用和iowait导致。
这里更新了最新版的sysstat包
[root@localhost ~]# wget http://pagesperso-orange.fr/sebastien.godard/sysstat-12.1.1-1.x86_64.rpm
[root@localhost ~]# rpm -Uvh sysstat-12.1.1-1.x86_64.rpm
那么到底是哪个进程,导致系统CPU使用率特别高,及iowait特别高呢?
[root@localhost ~]# pidstat -u 5 1
Linux 3.10.0-514.16.1.el7.x86_64 (localhost.localdomain) 11/24/2018 _x86_64_ (16 CPU)
02:34:53 AM UID PID %usr %system %guest %wait %CPU CPU Command
02:34:58 AM 0 730 0.00 0.20 0.00 0.00 0.20 12 xfsaild/vda6
02:34:58 AM 0 1471 0.00 0.20 0.00 0.00 0.20 10 kworker/10:2
02:34:58 AM 0 3042 0.00 0.40 0.00 0.00 0.40 7 kworker/7:1H
02:34:58 AM 0 11617 0.00 1.59 0.00 0.00 1.59 2 kworker/u32:1
02:34:58 AM 0 15272 0.00 91.43 0.00 0.40 91.43 7 stress
02:34:58 AM 0 15273 0.00 0.20 0.00 0.00 0.20 14 kworker/u32:0
02:34:58 AM 0 15274 0.20 0.40 0.00 0.00 0.60 5 pidstat
通过以上的信息,可以很清晰的看到,是由于stress进程出现了大量的系统使用。
场景三:大量进程的场景
当系统中运行进程超出CPU运行能力时,就会出现等待CPU的进程。
我们打开终端一:使用stress模拟24个进程:
[root@localhost ~]# stress -c 24 --timeout 3600
stress: info: [11726] dispatching hogs: 24 cpu, 0 io, 0 vm, 0 hdd
打开终端二:看下当前的负载值
[root@localhost ~]# uptime
02:20:36 up 1 day, 2:12, 4 users, load average: 17.22, 5.98, 2.61
[root@localhost ~]# uptime
02:20:52 up 1 day, 2:13, 4 users, load average: 18.72, 6.86, 2.95
[root@localhost ~]# uptime
02:24:03 up 1 day, 2:16, 4 users, load average: 23.77, 14.94, 6.85
打开终端三:看下进程的资源使用信息
[root@localhost ~]# pidstat -u 5 1
Linux 3.10.0-514.16.1.el7.x86_64 (localhost.localdomain) 11/24/2018 _x86_64_ (16 CPU)
02:28:14 AM UID PID %usr %system %guest %wait %CPU CPU Command
02:28:19 AM 0 43 0.00 0.20 0.00 0.00 0.20 7 ksoftirqd/7
02:28:19 AM 0 2292 0.20 0.00 0.00 0.00 0.20 11 dstat
02:28:19 AM 0 11727 48.81 0.00 0.00 44.05 48.81 5 stress
02:28:19 AM 0 11728 44.64 0.00 0.00 0.00 44.64 12 stress
02:28:19 AM 0 11729 41.27 0.00 0.00 49.60 41.27 11 stress
02:28:19 AM 0 11730 46.03 0.00 0.00 41.27 46.03 2 stress
02:28:19 AM 0 11731 59.92 0.00 0.00 30.16 59.92 15 stress
02:28:19 AM 0 11732 47.62 0.00 0.00 25.60 47.62 13 stress
02:28:19 AM 0 11733 65.67 0.00 0.00 22.02 65.67 2 stress
02:28:19 AM 0 11734 41.67 0.00 0.00 50.40 41.67 10 stress
02:28:19 AM 0 11735 54.17 0.00 0.00 32.34 54.17 15 stress
02:28:19 AM 0 11736 42.06 0.00 0.00 50.20 42.06 6 stress
02:28:19 AM 0 11737 35.91 0.00 0.00 29.96 35.91 3 stress
02:28:19 AM 0 11738 50.20 0.00 0.00 5.16 50.20 10 stress
02:28:19 AM 0 11739 42.06 0.00 0.00 49.60 42.06 6 stress
02:28:19 AM 0 11740 58.73 0.00 0.00 34.92 58.73 4 stress
02:28:19 AM 0 11741 46.63 0.00 0.00 13.49 46.63 1 stress
02:28:19 AM 0 11742 43.45 0.00 0.00 50.79 43.45 14 stress
02:28:19 AM 0 11743 44.05 0.00 0.00 45.24 44.05 7 stress
02:28:19 AM 0 11744 56.55 0.00 0.00 12.70 56.55 0 stress
02:28:19 AM 0 11745 46.23 0.00 0.00 49.80 46.23 5 stress
02:28:19 AM 0 11746 49.40 0.00 0.00 41.27 49.40 11 stress
02:28:19 AM 0 11747 43.65 0.00 0.00 49.40 43.65 14 stress
02:28:19 AM 0 11748 59.33 0.00 0.00 0.99 59.33 8 stress
02:28:19 AM 0 11749 46.43 0.00 0.00 45.24 46.43 4 stress
02:28:19 AM 0 11750 51.19 0.00 0.00 24.60 51.19 9 stress
02:28:19 AM 0 14276 0.00 0.40 0.00 0.20 0.40 10 pidstat
我们发现,运行的24个stress进程,出现了资源争抢的问题,既然出现了资源争抢,就会出现等待时间wait。
思考:
iowait多少算高?
注意,iowait不等于cpu wait�