怎么理解“平均负载”
系统变慢第一件事就是执行top或者uptime命令,来了解系统的负载情况,比如下面
[root@mysqlhq ~]# uptime
15:11:14 up 63 days, 5:03, 2 users, load average: 0.00, 0.02, 0.05
15:11:14 //当前时间
up 63 days, 5:03 //系统运行时间
2 users //正在登陆用户数
load average: 0.00, 0.02, 0.05 ,依次是过去1分钟、5分钟、15分钟的平均负载。
--平均负载
,单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和cpu使用率并没有直接关系。
所谓可运行状态的进程,是指正在使用cpu或者等待cpu的进程,也就是ps命令经常看见的,处于R状态(running或runnable)的进程。
不可中断的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断,比如最常见的是等待硬件设备的IO响应,也就是在ps命令看到的D状态(uninterruptible Sleep,也称为Disk Sleep)的进程。
比如,当一个进程向磁盘写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这时候的进程就处于不个中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。
所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
可以简单理解为,平均负载其实就是平均活跃进程数。直观上的理解就是单位时间内活跃的进程数,但它实际上是活跃进程数的指数衰减平均值。可以直接当成活跃进程的平均值也没问题。
既然是平均活跃进程数,最理想就是每个cpu上都刚好运行一个进程,这样每个cpu都得到充分利用。当负载为2:
--在只有2个cpu的系统上,意味着所有的cpu都刚好被完全占用
--在4个cpu的系统,意味着cpu有50%的空闲
--在只有1个cpu的系统上,有一半的进程竞争不到cpu
平均负载为多少时合适
在uptime出现的3个负载值,到底多大说明负载高,多小说明负载低呢
平均负载最理想的情况是等于cpu数,所以在判断平均负载时,首先知道cpu
[root@mysqlhq ~]# grep 'model name' /proc/cpuinfo | wc -l
1
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
查看CPU信息(型号)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
uptime的3个平均负载值,都需要看,分析系统负载趋势的数据来源
--如果1分钟、5分钟、15分钟的3个值基本相同或者相差不大,说明系统负载很平稳
--但如1分钟的值远小于15分钟的值,说明最近1分钟的负载在减少,过去15分钟的有很大的负载
--反过来,如果1分钟的值远大于15分钟,说明最近1分钟的负载在增加,这种增加有可能是临时性的,也可能会持续,可以持续观察。一旦一分钟的平均负载接近或超过cpu的个数,就意味着正在发生过载的问题,这时候就得分析。
举个例子,假设我们在一个单cpu的系统上看到平均负载为1.73,0.60,7.98,那么说明在过去一分钟内,系统有73%的超载,而在15分钟内,有698%(7.98-1)的超载,从整体趋势上看,系统的负载在降低。
在实际生产环境中,平均负载多高时,需要我们重点关注呢
当平均负载高于cpu数量70%的时候,需要分析排查负载高的问题。一旦负载过高就可能导致进程响应变慢,进而影响服务的正常功能。
但70%的数值并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显变化时,再去做分析和调查。
--平均负载和cpu使用率
平均负载不仅包括正在使用cpu的进程,还包括等待cpu和等待IO的进程。
而cpu使用率,是单位时间内cpu繁忙情况的统计:
--cpu密集型进程,使用大量cpu会导致平均负载升高,但这2者一致。
--io密集型进程,等待io也会导致平均负载升高,但cpu使用率不一定很高。
--大量等待cpu的进程调度也会导致平均负载升高,但cpu使用率也会比较高。
平均负载案例分析
下面的情况,分别使用iostat、mpstat、pidstat等工具,找出平均负载升高的根源。
环境准备:
[root@mysqlhq ~]# yum install stress sysstat
--stress是linux系统压力测试工具,这里用作异常进程模拟平均负载升高的场景。
--sysstat包含常用的linux的性能工具,用来监控和分析系统的性能(mpstat,pidstat)。
--mpstat是一个常用的多核cpu性能分析工具,用来实时查看每个cpu的性能指标,以及所有cpu的平均指标。
--pidstat用来实时查看进程的cpu,内存,io以及上下午切换等性能指标。
[root@mysqlhq ~]# uptime
16:30:25 up 63 days, 6:22, 4 users, load average: 0.13, 0.10, 0.12
[root@mysqlhq soft]# wget http://people.seas.harvard.edu/~apw/stress/stress-1.0.4.tar.gz
[root@mysqlhq soft]# tar -zxvf stress-1.0.4.tar.gz
[root@mysqlhq soft]# cd stress-1.0.4/
[root@mysqlhq stress-1.0.4]# ./configure
[root@mysqlhq stress-1.0.4]# make && make install
[root@mysqlhq stress-1.0.4]# /usr/local/bin/stress --help
场景1:cpu密集型进程
在一个终端运行stress命令,模拟1个cpu使用100%的场景
[root@mysqlhq ~]# /usr/local/bin/stress --cpu 1 --timeout 600
stress: info: [14110] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
在第二个终端运行uptime查看平均负载均衡的变化情况
--# -d参数表示高亮显示变化的区域
[root@mysqlhq ~]# watch -d uptime
在第三个终端运行mpstat查看cpu使用率的变化情况
--P ALL 表示监控所有cpu,后面数字5表示时间间隔
[root@mysqlhq ~]# mpstat -P ALL 5
05:31:19 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:31:24 PM all 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
05:31:24 PM 0 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
从第二个终端看到,1分钟的平均负载均衡会慢慢增加到1,而终端3看到,有一个cpu使用率100%,但是它的iowait只有0,说明平均负载的升高正是由于cpu使用率100%
到底哪个进程导致cpu使用率100%呢
--#间隔5秒后输出一组数据
[root@mysqlhq ~]# pidstat -u 5 1
Linux 3.10.0-514.ky3.kb3.x86_64 (mysqlhq) 12/03/2018 _x86_64_ (1 CPU)
05:33:59 PM UID PID %usr %system %guest %CPU CPU Command
05:34:04 PM 42 2276 0.22 0.00 0.00 0.22 0 gnome-shell
05:34:04 PM 0 14111 98.71 0.00 0.00 98.71 0 stress
05:34:04 PM 1000 14899 0.22 0.22 0.00 0.43 0 mysqld
可以明显看到stress进程的cpu使用率100%
场景2:I/O密集型进程
首先模拟stress命令,这次模拟io压力,不停的执行sync
[root@mysqlhq ~]# /usr/local/bin/stress -i 1 --timeout 600
stress: info: [16898] dispatching hogs: 0 cpu, 1 io, 0 vm, 0 hdd
第二个终端还是查看uptime,平均负载
[root@mysqlhq ~]# watch -d uptime
第三个运行mpstat查看cpu使用率
--#显示所有cpu的指标,并间隔5秒输出一组数据
[root@mysqlhq ~]# mpstat -P ALL 5
05:49:16 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:49:21 PM all 0.60 0.00 99.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
05:49:21 PM 0 0.60 0.00 99.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
[root@mysqlhq ~]# pidstat -u 5 1
Linux 3.10.0-514.ky3.kb3.x86_64 (mysqlhq) 12/03/2018 _x86_64_ (1 CPU)
05:50:17 PM UID PID %usr %system %guest %CPU CPU Command
05:50:22 PM 0 9 0.00 0.20 0.00 0.20 0 rcu_sched
05:50:22 PM 1000 14899 0.00 0.40 0.00 0.40 0 mysqld
05:50:22 PM 1001 14982 0.00 0.20 0.00 0.20 0 zabbix_agentd
05:50:22 PM 0 15470 0.20 0.20 0.00 0.40 0 watch
05:50:22 PM 0 15754 0.00 0.20 0.00 0.20 0 kworker/u2:0
05:50:22 PM 0 16899 0.00 98.80 0.00 98.80 0 stress
05:50:22 PM 0 17149 0.00 0.20 0.00 0.20 0 kworker/u2:2
查看进程,还是stress导致cpu使用100%
场景3:大量进程的场景
当系统中运行进程超出cpu运行能力时,就会出现等待cpu的进程
使用stress,模拟8个进程
[root@mysqlhq ~]# /usr/local/bin/stress -c 8 --timeout 600
stress: info: [5709] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd
由于系统只有1个cpu,查看uptime
[root@mysqlhq ~]# uptime
11:17:20 up 64 days, 1:09, 6 users, load average: 8.97, 3.92, 1.58
查看pidstat
[root@mysqlhq ~]# pidstat -u 5 1
Linux 3.10.0-514.ky3.kb3.x86_64 (mysqlhq) 12/04/2018 _x86_64_ (1 CPU)
11:15:50 AM UID PID %usr %system %guest %CPU CPU Command
11:15:55 AM 1000 4122 2.07 2.07 0.00 4.14 0 mysqld
11:15:55 AM 0 5710 12.42 0.00 0.00 12.42 0 stress
11:15:55 AM 0 5711 12.42 0.00 0.00 12.42 0 stress
11:15:55 AM 0 5712 12.42 0.00 0.00 12.42 0 stress
11:15:55 AM 0 5713 12.22 0.00 0.00 12.22 0 stress
11:15:55 AM 0 5714 12.42 0.00 0.00 12.42 0 stress
11:15:55 AM 0 5715 12.42 0.00 0.00 12.42 0 stress
11:15:55 AM 0 5716 12.63 0.00 0.00 12.63 0 stress
11:15:55 AM 0 5717 12.22 0.00 0.00 12.22 0 stress
11:15:55 AM 0 5834 0.00 0.21 0.00 0.21 0 pidstat
可以看出,8个进程争抢1个cpu,每个进程等待cpu的时间,每个%wait列
由于我这里测试的是麒麟系统,可能跟centos的结果有一些不一样(没有%wait)
[root@mysqlhq ~]# cat /etc/issue
\nKylin 3.3
Kernel \r on an \m
\KRelease (Trial)
也肯能是版本sysstat比较老的问题
[root@mysqlhq ~]# rpm -q sysstat
sysstat-10.1.5-13.el7.x86_64
[root@mysqlhq ~]# rpm -e sysstat-10.1.5-13.el7.x86_64
[root@mysqlhq soft]# tar zxvf sysstat-11.5.5.tar.gz
[root@mysqlhq sysstat-11.5.5]# ./configure
小结:
上面的3个案例,来归纳一下平均负载
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况,但只看平均负载本身,并不能直接发行,到底是哪里出现了瓶颈,所以,在理解平均负载时,也要注意:
--平均负载高可能是cpu密集型进程导致的
--平均负载高并不一定代表cpu使用率高,还有可能是I/O更繁忙了
--当发现负载高的时候,可以使用mpstat、pidstat等工具,辅助分析负载的来源。