linux性能调优笔记
一、平均负载与CPU使用率并没有直接关系
1.平均负载
在单位时间内,系统处于可运行状态和不可中断状态的平均进程数也就是平均活跃进程数,它和cpu使用率并没有直接关系,
可运行状态:
正在使用的cpu或者正在等待cpu的进程
不可中断状态
进程是正处于内核关键流程中的进程,并且这些流程是不可中断的,比如最常见的是等待硬件设备I/O响应,也就是我们在ps命令中看到的D状态的状态(硬件中断为硬中断)
或者中断打断的 ,这个时候的 进程处于不可中断状态,如果此时的进程被打断了 ,就容易出现磁盘数据与进程不一致的问题
所以,不可中断状态实际上是系统对进程和硬件的一种保护机制
2、当平均负载2时,意味着什么呢?
既然是平均的活跃进程数,那么最理想的,就是每个cpu上都刚好运行着一个进程,这样每个cpu都得到了充分利用,比如当平均负载2时,意味着什么呢?
1、在只有2个CPU的系统上,意味着所有的CPU都刚好被完全占用
2、在4个CPU的系统上,意味着CPU有50%的空闲
3、而在只有1个CPU的系统上,则意味着有一半的进程竞争不到CPU
二、平均负载为多少时合理
平均负载最理想的情况等于CPU的个数,即平均负载数等于CPU数
1、系统有几个CPU?
关于 grep 和 wc 的用法请查询它们的手册或者网络搜索
这里我给出了两个命令去查询CPU数量
lighthouse@VM-24-16-ubuntu:~$ lscpu | grep CPU
CPU op-mode(s): 32-bit, 64-bit
CPU(s): 2
On-line CPU(s) list: 0,1
Model name: Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz
CPU family: 6
NUMA node0 CPU(s): 0,1
Vulnerability Mds: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Mmio stale data: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Tsx async abort: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
lighthouse@VM-24-16-ubuntu:~$ grep 'model name' /proc/cpuinfo | wc -l
2
我们通过命令查询到机器的CPU数为2。
注:当平均负载高于 CPU 数量 70% 排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。
三、平均负载与 CPU 使用率
这两个概念是完全不同的,学习的时候重点区分
平均负载
1、正在使用 CPU 的进程,
2、等待 CPU
3、等待 I/O 的进程。
CPU使用率
是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应
1、CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者一直的
2、I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
3、大量等待 CPU 的进程调度也会导致平均负载升高,此时的CPU 使用率也会比较高
四、场景实战
1、环境与测试工具
1.操作系统
lighthouse@VM-24-16-ubuntu:~$ cat /proc/version
Linux version 5.15.0-106-generic (buildd@lcy02-amd64-017) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #116-Ubuntu SMP Wed Apr 17 09:17:56 UTC 2024
2.测试工具
lighthouse@VM-24-16-ubuntu:~$ sudo -i
root@VM-24-16-ubuntu:~# apt install -y stress-ng sysstat
2、场景一:CPU 密集型进程
机器CPU数刚刚通过命令的方式已经查询到是2个,现在用stress命令,对一个CPU进行压测,并观察现象。
1.窗口1
使用stress命令对一个CPU进行压力测试,测试时间为600s。
lighthouse@VM-24-16-ubuntu:~$ stress --cpu 1 --timeout 600
stress: info: [3567758] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
2.窗口2
使用uptime或者top命令观察机器的负载情况。
lighthouse@VM-24-16-ubuntu:~$ uptime
14:24:23 up 6 days, 21:21, 4 users, load average: 1.10, 0.58, 0.33
我这里的机器的负载会慢慢变到1左右,这是验证了我们已经用一个CPU已经被占用了。
3.窗口3
使用mpstat 命令查看机器性能。
mpstat是Multiprocessor Statistics的缩写,是实时系统监控工具。其报告与CPU的一些统计信息,这些信息存放在/proc/stat文件中。在多CPUs系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息。mpstat最大的特点是:可以查看多核心cpu中每个计算核心的统计数据;而类似工具vmstat只能查看系统整体cpu情况。
#-P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
lighthouse@VM-24-16-ubuntu:~$ mpstat -P ALL 5
lighthouse@VM-24-16-ubuntu:~$ mpstat -P ALL 5
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
02:30:37 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
02:30:42 PM all 58.50 0.00 4.50 0.10 0.00 0.30 0.00 0.00 0.00 36.60
02:30:42 PM 0 31.93 0.00 6.02 0.00 0.00 0.40 0.00 0.00 0.00 61.65
02:30:42 PM 1 84.86 0.00 2.99 0.20 0.00 0.20 0.00 0.00 0.00 11.75
02:30:42 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
02:30:47 PM all 52.15 0.00 3.50 0.20 0.00 0.30 0.00 0.00 0.00 43.86
02:30:47 PM 0 4.79 0.00 6.59 0.40 0.00 0.60 0.00 0.00 0.00 87.62
02:30:47 PM 1 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
正好有一个 CPU 的使用率接近为 100%,但其他的 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。
注:我们要看%usr和%sys列,%usr 列显示了用户CPU时间的百分比,%sys 列显示了内核(系统)CPU时间的百分比,而 %idle 列则表示CPU处于空闲状态的时间百分比。要了解CPU的整体使用率,你可以关注 %usr 和 %sys 列的总和,这将给出CPU在执行用户进程和系统任务上的忙碌程度。其他列提供了关于等待I/O、硬件中断、软件中断等的额外细节。
那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?你可以使用 pidstat 来查询。
lighthouse@VM-24-16-ubuntu:~$ pidstat -u 5 1
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
02:37:35 PM UID PID %usr %system %guest %wait %CPU CPU Command
02:37:40 PM 0 13 0.00 0.20 0.00 0.00 0.20 0 ksoftirqd/0
02:37:40 PM 0 8466 0.20 0.00 0.00 0.00 0.20 0 barad_agent
02:37:40 PM 0 8467 0.80 0.60 0.00 0.00 1.40 1 barad_agent
02:37:40 PM 0 8793 0.20 0.20 0.00 0.00 0.40 0 tat_agent
02:37:40 PM 0 3176583 1.20 0.80 0.00 0.00 2.00 1 YDService
02:37:40 PM 1001 3397877 0.00 0.20 0.00 0.00 0.20 0 orca-data.sh
02:37:40 PM 0 3588695 0.00 0.20 0.00 0.00 0.20 0 kworker/u4:1-events_power_efficient
02:37:40 PM 1001 3591563 0.20 0.00 0.00 0.00 0.20 0 node
02:37:40 PM 1001 3591963 2.40 0.60 0.00 0.80 2.99 0 node
02:37:40 PM 1001 3611615 98.60 0.00 0.00 1.20 98.60 1 stress
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 13 0.00 0.20 0.00 0.00 0.20 - ksoftirqd/0
Average: 0 8466 0.20 0.00 0.00 0.00 0.20 - barad_agent
Average: 0 8467 0.80 0.60 0.00 0.00 1.40 - barad_agent
Average: 0 8793 0.20 0.20 0.00 0.00 0.40 - tat_agent
Average: 0 3176583 1.20 0.80 0.00 0.00 2.00 - YDService
Average: 1001 3397877 0.00 0.20 0.00 0.00 0.20 - orca-data.sh
Average: 0 3588695 0.00 0.20 0.00 0.00 0.20 - kworker/u4:1-events_power_efficient
Average: 1001 3591563 0.20 0.00 0.00 0.00 0.20 - node
Average: 1001 3591963 2.40 0.60 0.00 0.80 2.99 - node
Average: 1001 3611615 98.60 0.00 0.00 1.20 98.60 - stress
从这里可以明显看到,stress 进程的 CPU 使用率为 98.60
所以我们得到了stress的CPU的占用接近100%,pid号为3611615 。执行kill命令在进行观察。
lighthouse@VM-24-16-ubuntu:~$ kill -9 3611615
观察uptime的负载数值明显下降,mpstat 观察CPU的使用率
3、场景二:I/O 密集型进程
1.窗口1
使用stress命令对磁盘I/O进行压力测试
lighthouse@VM-24-16-ubuntu:~$ stress-ng -i 1 --hdd 1 --timeout 600
stress-ng: info: [3640301] setting to a 600 second (10 mins, 0.00 secs) run per stressor
stress-ng: info: [3640301] dispatching hogs: 1 io, 1 hdd
2.窗口2
观察机器的负载情况
# -d 参数表示高亮显示变化的区域
lighthouse@VM-24-16-ubuntu:~$ watch -d uptime
Every 2.0s: uptime VM-24-16-ubuntu: Wed Jun 5 14:48:19 2024
14:48:19 up 6 days, 21:45, 6 users, load average: 4.05, 1.84, 1.08
3.窗口3
lighthouse@VM-24-16-ubuntu:~$ mpstat -P ALL 5 1
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
02:50:00 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
02:50:05 PM all 8.41 0.00 10.77 76.72 0.00 0.00 0.00 0.00 0.00 4.10
02:50:05 PM 0 8.59 0.00 9.41 80.57 0.00 0.00 0.00 0.00 0.00 1.43
02:50:05 PM 1 8.23 0.00 12.14 72.84 0.00 0.00 0.00 0.00 0.00 6.79
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 8.41 0.00 10.77 76.72 0.00 0.00 0.00 0.00 0.00 4.10
Average: 0 8.59 0.00 9.41 80.57 0.00 0.00 0.00 0.00 0.00 1.43
Average: 1 8.23 0.00 12.14 72.84 0.00 0.00 0.00 0.00 0.00 6.79
1 分钟的平均负载会慢慢增加到4
其中一个 CPU 的系统 CPU 使用率升高到了 8 ,而 iowait 高达 80%。这说明,平均负载的升高是由于 iowait 的升高。
那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?
lighthouse@VM-24-16-ubuntu:~$ pidstat -u 5 1
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
03:59:14 PM UID PID %usr %system %guest %wait %CPU CPU Command
03:59:19 PM 0 8466 0.20 0.00 0.00 0.00 0.20 0 barad_agent
03:59:19 PM 0 8467 0.40 0.20 0.00 0.00 0.60 0 barad_agent
03:59:19 PM 0 8793 0.20 0.00 0.00 0.00 0.20 1 tat_agent
03:59:19 PM 0 3161835 0.00 0.20 0.00 0.00 0.20 1 kworker/1:0-events
03:59:19 PM 0 3176425 0.00 0.20 0.00 0.00 0.20 0 kworker/0:0-events
03:59:19 PM 0 3176583 1.20 0.80 0.00 0.00 2.00 0 YDService
03:59:19 PM 1001 3591963 1.60 0.80 0.00 0.00 2.40 0 node
03:59:19 PM 1001 3591970 0.20 0.00 0.00 0.00 0.20 0 node
03:59:19 PM 1001 3801973 0.00 0.20 0.00 0.00 0.20 0 top
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 8466 0.20 0.00 0.00 0.00 0.20 - barad_agent
Average: 0 8467 0.40 0.20 0.00 0.00 0.60 - barad_agent
Average: 0 8793 0.20 0.00 0.00 0.00 0.20 - tat_agent
Average: 0 3161835 0.00 0.20 0.00 0.00 0.20 - kworker/1:0-events
Average: 0 3176425 0.00 0.20 0.00 0.00 0.20 - kworker/0:0-events
Average: 0 3176583 1.20 0.80 0.00 0.00 2.00 - YDService
Average: 1001 3591963 1.60 0.80 0.00 0.00 2.40 - node
Average: 1001 3591970 0.20 0.00 0.00 0.00 0.20 - node
Average: 1001 3801973 0.00 0.20 0.00 0.00 0.20 - top
lighthouse@VM-24-16-ubuntu:~$ pidstat -u 5 1
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
03:59:28 PM UID PID %usr %system %guest %wait %CPU CPU Command
03:59:33 PM 0 8466 0.20 0.00 0.00 0.00 0.20 0 barad_agent
03:59:33 PM 0 8467 0.60 0.40 0.00 0.00 1.00 0 barad_agent
03:59:33 PM 102 3129426 0.00 0.20 0.00 0.00 0.20 0 systemd-resolve
03:59:33 PM 0 3176583 1.20 1.20 0.00 0.00 2.40 0 YDService
03:59:33 PM 1001 3591963 1.20 0.60 0.00 0.60 1.80 0 node
03:59:33 PM 1001 3797251 0.20 0.00 0.00 0.20 0.20 1 orca-data.sh
03:59:33 PM 1001 3801973 0.00 0.20 0.00 0.00 0.20 1 top
03:59:33 PM 1001 3837526 98.80 0.00 0.00 1.20 98.80 1 stress
03:59:33 PM 1001 3837832 0.00 0.20 0.00 0.00 0.20 0 pidstat
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 8466 0.20 0.00 0.00 0.00 0.20 - barad_agent
Average: 0 8467 0.60 0.40 0.00 0.00 1.00 - barad_agent
Average: 102 3129426 0.00 0.20 0.00 0.00 0.20 - systemd-resolve
Average: 0 3176583 1.20 1.20 0.00 0.00 2.40 - YDService
Average: 1001 3591963 1.20 0.60 0.00 0.60 1.80 - node
Average: 1001 3797251 0.20 0.00 0.00 0.20 0.20 - orca-data.sh
Average: 1001 3801973 0.00 0.20 0.00 0.00 0.20 - top
Average: 1001 3837526 98.80 0.00 0.00 1.20 98.80 - stress
Average: 1001 3837832 0.00 0.20 0.00 0.00 0.20 - pidstat
4、场景三:大量进程的场景
当系统中运行进程超出CPU运行能力时,就会出现等待CPU的进程。
比如,我们还是使用stress,但这次模拟的 是8个进程:
1.窗口1
lighthouse@VM-24-16-ubuntu:~$ stress -c 8 --timeout 600
stress: info: [3849461] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd
2.窗口2
lighthouse@VM-24-16-ubuntu:~$ uptime
16:04:32 up 6 days, 23:01, 4 users, load average: 7.09, 2.96, 1.50
3.窗口3
lighthouse@VM-24-16-ubuntu:~$ pidstat -u 5 1
Linux 5.15.0-106-generic (VM-24-16-ubuntu) 06/05/2024 _x86_64_ (2 CPU)
04:05:01 PM UID PID %usr %system %guest %wait %CPU CPU Command
04:05:06 PM 0 14 0.00 0.20 0.00 0.00 0.20 0 rcu_sched
04:05:06 PM 0 8467 0.60 0.20 0.00 0.00 0.79 0 barad_agent
04:05:06 PM 0 8793 0.20 0.00 0.00 0.00 0.20 0 tat_agent
04:05:06 PM 0 3176583 1.19 0.99 0.00 0.00 2.18 0 YDService
04:05:06 PM 1001 3591563 0.40 0.00 0.00 0.20 0.40 0 node
04:05:06 PM 1001 3591963 1.79 0.60 0.00 3.17 2.38 0 node
04:05:06 PM 1001 3849462 23.02 0.20 0.00 76.39 23.21 1 stress
04:05:06 PM 1001 3849463 22.42 0.00 0.00 77.18 22.42 1 stress
04:05:06 PM 1001 3849464 22.62 0.20 0.00 76.98 22.82 0 stress
04:05:06 PM 1001 3849465 22.82 0.00 0.00 76.59 22.82 0 stress
04:05:06 PM 1001 3849466 23.81 0.00 0.00 76.19 23.81 1 stress
04:05:06 PM 1001 3849467 22.82 0.00 0.00 76.79 22.82 0 stress
04:05:06 PM 1001 3849468 22.62 0.00 0.00 76.98 22.62 0 stress
04:05:06 PM 1001 3849469 23.02 0.00 0.00 76.39 23.02 1 stress
04:05:06 PM 1001 3853699 0.00 0.20 0.00 0.00 0.20 1 pidstat
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 14 0.00 0.20 0.00 0.00 0.20 - rcu_sched
Average: 0 8467 0.60 0.20 0.00 0.00 0.79 - barad_agent
Average: 0 8793 0.20 0.00 0.00 0.00 0.20 - tat_agent
Average: 0 3176583 1.19 0.99 0.00 0.00 2.18 - YDService
Average: 1001 3591563 0.40 0.00 0.00 0.20 0.40 - node
Average: 1001 3591963 1.79 0.60 0.00 3.17 2.38 - node
Average: 1001 3849462 23.02 0.20 0.00 76.39 23.21 - stress
Average: 1001 3849463 22.42 0.00 0.00 77.18 22.42 - stress
Average: 1001 3849464 22.62 0.20 0.00 76.98 22.82 - stress
Average: 1001 3849465 22.82 0.00 0.00 76.59 22.82 - stress
Average: 1001 3849466 23.81 0.00 0.00 76.19 23.81 - stress
Average: 1001 3849467 22.82 0.00 0.00 76.79 22.82 - stress
Average: 1001 3849468 22.62 0.00 0.00 76.98 22.62 - stress
Average: 1001 3849469 23.02 0.00 0.00 76.39 23.02 - stress
Average: 1001 3853699 0.00 0.20 0.00 0.00 0.20 - pidstat
可以看出,8 个进程在争抢 2 个 CPU,每个进程等待CPU 的时间(也就是代码块中的 %wait 列)高达 75%这些超出 CPU 计算能力的进程,最终导致 CPU 过载。