Linux 性能观测之CPU平均负载

2024-08-25 02:20

本文主要是介绍Linux 性能观测之CPU平均负载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面


  • 博文内容涉及 Linux 平均负载认知
  • 以及对造成平均负载波动的场景认知:
    • CPU 密集型进程
    • I/O 密集型进程
    • 大量进程
  • 理解不足小伙伴帮忙指正 😃,生活加油

99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式


Linux 平均负载指标可以说是最直观的查看 Linux 性能负载的指标,可以对 CPU 性能有直观的体现,性能调优大神 Brendan Gregg 在 Linux 60s 性能分析中最先讲到的工具为 uptime ,一起来看下如何理解这些平均负载指标

平均负载

查看 Linux 平均负载的命令有两个,一个使用使用 uptime 命令

liruilong@liruilongs:~$ uptime19:35:03 up 1 day,  5:36,  0 users,  load average: 0.52, 0.58, 0.59
liruilong@liruilongs:~$

在实际使用中可以配合 watch -d 命令实时监控

┌──[root@liruilongs.github.io]-[~] 
└─$watch -d uptime 

另一个是是使用 top 命令来查看,实际上显示的也是 uptime 输出的数据

┌──[root@liruilongs.github.io]-[~] 
└─$toptop - 11:33:19 up 1 min,  1 user,  load average: 0.88, 0.40, 0.15

load average 对应的值即为平均负载,先来看下帮助文档如何描述 平均负载

uptime 命令用于显示系统已运行的时间,并提供系统负载平均值的信息。以下是 uptime 命令提供的信息解释:

┌──[liruilong@liruilongs.github.io]-[~]
└─$man uptime
UPTIME(1)                                           User Commands                                           UPTIME(1)NAMEuptime - Tell how long the system has been running.SYNOPSISuptime [options]DESCRIPTIONuptime  gives a one line display of the following information.  The current time, how long the system has beenrunning, how many users are currently logged on, and the system load averages for the past 1, 5, and  15  min‐utes.This is the same information contained in the header line displayed by w(1).System  load  averages  is  the  average  number of processes that are either in a runnable or uninterruptablestate.  A process in a runnable state is either using the CPU or waiting to use the CPU.  A process  in  unin‐terruptable  state is waiting for some I/O access, eg waiting for disk.  The averages are taken over the threetime intervals.  Load averages are not normalized for the number of CPUs in a system, so a load average  of  1means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.......................................

uptime 可以快速查看当前系统时间以及运行时间,总的登录用户, 以及平均负载

  • 当前时间:显示执行uptime命令时的系统当前时间。
  • 系统运行时间:显示系统自上次引导或重新启动以来的运行时间。以"X天X小时X分钟"的格式显示。
  • 用户数量:表示当前登录到系统的用户数量
  • 系统负载平均值:显示过去1分钟、5分钟和15分钟系统负载平均值。负载平均值代表处于运行状态或等待运行状态的平均进程数量(平均活跃进程数)。它指示系统的活动水平和资源利用程度。负载平均值并不针对系统中的CPU核数进行归一化,它和 CPU 使用率并没有直接关系

如何理解平均负载指标

┌──[root@liruilongs.github.io]-[~]
└─$uptime11:14:26 up 16 min,  1 user,  load average: 21.37, 18.64, 16.25

这些数字包含了想要在 CPU 上运行的进程( ps 命令处于 R 状态(Running 或 Runnable)的进程),同时也包含了阻塞在不可中断IO(通常是磁盘 I/O, ps 命令处于 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程)上的进程。这给出了一个高层次视角的资源负载(或者说资源需求)

当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题.所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制

3个数字分别是指数衰减的1分钟/5分钟/15分钟滑动窗累积值(可以直接理解为 单位时间内的活跃进程数)。通过这3个值可以大致了解负载随时间变化的情况。平均负载要结合CPU 逻辑核数来观察。

快速查看CPU核数可以通过top命令然后按1键查看

top - 11:21:36 up 23 min,  1 user,  load average: 22.36, 19.03, 17.14
Tasks: 443 total,   5 running, 438 sleeping,   0 stopped,   0 zombie
%Cpu0  :  6.4 us,  5.4 sy,  0.0 ni, 77.9 id,  0.0 wa,  4.4 hi,  5.9 si,  0.0 st
%Cpu1  :  9.2 us, 12.2 sy,  0.0 ni, 71.9 id,  3.6 wa,  2.0 hi,  1.0 si,  0.0 st
%Cpu2  :  4.8 us,  3.6 sy,  0.0 ni, 68.8 id,  4.8 wa, 18.0 hi,  0.0 si,  0.0 st
%Cpu3  :  4.5 us,  5.5 sy,  0.0 ni, 72.7 id,  2.7 wa,  0.5 hi, 14.1 si,  0.0 st
MiB Mem :  15730.5 total,   7489.9 free,   6823.5 used,   1417.2 buff/cache
MiB Swap:   2068.0 total,   2068.0 free,      0.0 used.   8496.2 avail Mem

或者查看 CPU 信息

liruilong@liruilongs:~$ grep 'model name' /proc/cpuinfo | wc -l
8

top命令然后按1键的基础上可以按 t 键对数据进行可视化展示,可以直观的看到 CPU 的使用率。

top - 11:22:26 up 24 min,  1 user,  load average: 15.02, 17.58, 16.74
Tasks: 449 total,  19 running, 430 sleeping,   0 stopped,   0 zombie
%Cpu0  :  24.5/37.1   62[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||                                    ]
%Cpu1  :  15.5/28.0   43[||||||||||||||||||||||||||||||||||||||||                                                     ]
%Cpu2  :  37.9/61.1   99[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]
%Cpu3  :  15.8/49.7   66[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||                                ]

平均负载为多少时合理,上面的例子显示负载最近有大幅的提升。一般情况下(还受到其他因素的影响,I/O 操作等),负载数与系统 CPU 核数的关系可以用以下规则来理解:

如果负载数小于 CPU 核数的70-80%:这通常表示系统的负载较轻,有足够的处理能力来处理所有的任务。系统响应时间较短,性能较好。

如果负载数接近或超过 CPU 核数的100%:这表示系统的负载很高,正在接近或达到其处理能力的极限。系统可能会出现延迟或变慢的情况,响应时间变长。

如果负载数远远超过 CPU 核数的100%:这表示系统的负载非常高,超过了系统的处理能力。系统可能会出现严重的延迟,甚至崩溃或无法响应。

平均负载有三个数值,到底该参考哪一个呢?

负载的平均值值得在排障过程中被首先进行检查,以确认性能问题是否还存在。在一个容错的环境中,一台存在性能问题的服务器,在你登录到机器上时,也许已经自动从服务列表中下线了。

一个较高的 15分钟负载与一个较低的1分钟负载同时出现,可能意味着已经错过了问题发生的现场。, 反之, 如果 1 分钟的负载 远大于 15 分钟的负载,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,CPU 可能已经处于饱和状态

┌──[root@vms100.liruilongs.github.io]-[~]
└─$uptime11:33:45 up 35 min,  1 user,  load average: 1.39, 6.06, 11.64
┌──[root@vms100.liruilongs.github.io]-[~]
└─$ 

平均负载与 CPU 使用率

平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 等待 I/O 的进程。

CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:

  • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
  • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
  • 大量等待 CPU 的进程调度,也会导致平均负载升高,此时的 CPU 使用率也会比较高。

平均负载指标理解案例

这里复现一下提到了三种不同情况的平均,这是当前正常环境的 平均负载情况

Every 2.0s: uptime                                                            Thu Aug 22 20:30:14 202420:30:14 up 10 min,  4 users,  load average: 1.97, 2.77, 1.71

CPU 密集型

通过 stress 命令来模拟 CPU 密集型操作,比如一些 AI 方面的预测,模型训练,这里的 CPU 1 为 对单个CPU 逻辑核进行密集性运算模拟,stress 命令是一个非常有用的 Linux 系统压力测试工具,它可以帮助开发者、系统管理员或测试人员对系统进行压力测试和性能评估。

┌──[root@vms100.liruilongs.github.io]-[~]
└─$stress --cpu 1 --timeout 300
stress: info: [8467] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd

查看 平均负载情况,5分钟内的平均负载升高

Every 2.0s: uptime                                                            Thu Aug 22 20:26:08 202420:26:08 up 6 min,  4 users,  load average: 3.41, 2.65, 1.32

通过 mpstat 命令来查看 CPU 负载信息,mpstat 命令是 Linux 系统上的一个重要的性能监控工具,它用于报告各个 CPU 的统计信息。

┌──[root@vms100.liruilongs.github.io]-[~]
└─$ mpstat -P ALL 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io)         2024年08月22日  _x86_64_     (4 CPU)20时22分25秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
20时22分30秒  all   30.43    0.00    2.95    0.00    0.00    0.78    0.00    0.00    0.00   65.84
20时22分30秒    0    5.53    0.00    3.62    0.00    0.00    1.70    0.00    0.00    0.00   89.15
20时22分30秒    1    5.24    0.00    3.56    0.00    0.00    0.63    0.00    0.00    0.00   90.57
20时22分30秒    2  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
20时22分30秒    3    7.66    0.00    4.97    0.00    0.00    0.83    0.00    0.00    0.00   86.54

可以看到 对于 CPU 逻辑核 2 两个异常的指标:

  • CPU用户态使用率(%usr) 为 100%
  • CPU 空闲率(%idle) 为 0%

在实际场景中,这种单个CPU 饱和的情况很少遇到,即便是遇到了,可以从下面的场景排查:

  • 一是要考虑是否代码中指定了CPU逻辑核数,需要排查代码逻辑
  • 二是对运行进程配置了CPU 亲和性,权重,需要排查服务启动文件,或者Cgroup(cpuset.cpus)等资源控制文件

大量进程的场景

这是相对常见的一种异常场景,大量的进程对CPU核内存都有影响,之前在生产中有遇到一次,代码BUG,建立了无数个FPT链接导致系统CPU核内存持续飙升。

这里我们同样使用 stress 模拟

┌──[root@vms100.liruilongs.github.io]-[~]
└─$stress -c 8 --timeout 600
stress: info: [18185] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd

可以看到 平均负载飙升,已经处于过度饱和状态

Every 2.0s: uptime                                                            Thu Aug 22 21:02:48 202421:02:48 up 8 min,  4 users,  load average: 5.71, 2.25, 0.97

通过 mpstat 观测CPU 使用率和空闲度,可以很直观的看到

┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat -P ALL 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io)         2024年08月22日  _x86_64_        (4 CPU)21时02分27秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
21时02分32秒  all   96.06    0.00    3.24    0.00    0.00    0.69    0.00    0.00    0.00    0.00
21时02分32秒    0   93.18    0.00    4.26    0.00    0.00    2.56    0.00    0.00    0.00    0.00
21时02分32秒    1   96.63    0.00    2.95    0.00    0.00    0.42    0.00    0.00    0.00    0.00
21时02分32秒    2   97.88    0.00    2.12    0.00    0.00    0.00    0.00    0.00    0.00    0.00
21时02分32秒    3   96.13    0.00    3.66    0.00    0.00    0.22    0.00    0.00    0.00    0.00

对于这种问题的定位可以直接使用 top 命令查看每个逻辑核的 CPU 使用情况,以及进程使用情况。

top - 21:06:03 up 11 min,  4 users,  load average: 6.86, 4.41, 2.09
Tasks: 274 total,   9 running, 176 sleeping,   0 stopped,   0 zombie
%Cpu0  :  85.5/11.2   97[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||   ]
%Cpu1  :  92.4/6.4    99[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  ]
%Cpu2  :  93.3/6.7   100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu3  :  89.3/9.8    99[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND25031 root      20   0    7320     96      0 R  51.0  0.0   0:15.58 stress25029 root      20   0    7320     96      0 R  45.0  0.0   0:15.80 stress25034 root      20   0    7320     96      0 R  41.7  0.0   0:15.28 stress25035 root      20   0    7320     96      0 R  37.7  0.0   0:14.60 stress25033 root      20   0    7320     96      0 R  35.4  0.0   0:14.84 stress25032 root      20   0    7320     96      0 R  34.4  0.0   0:14.74 stress25030 root      20   0    7320     96      0 R  32.8  0.0   0:14.77 stress25036 root      20   0    7320     96      0 R  32.1  0.0   0:14.86 stress1043 root      20   0 1348748 102384  48352 S  17.5  1.7   0:33.75 dockerd1962 root      20   0 10.696g 176412 107048 S  11.3  2.9   0:55.40 etcd1223 root      20   0 1019220  49628  27312 S  10.3  0.8   0:19.37 cri-dockerd1667 root      20   0 1806176 1.020g  72460 S   5.6 17.5   1:07.65 kube-apiserver943 root      20   0 1763192 112924  64100 S   5.0  1.8   0:22.20 kubelet3301 root      20   0 1673552  69068  46116 S   2.3  1.1   0:19.33 calico-node

生产场景中,可能进程特别多,但是每个进程CPU 使用率很小,我们可以通过下面的命令进行排查。分组统计当前系统所有进程

┌──[root@liruilongs.github.io]-[~] 
└─$ps aux | awk '{print $11}' | sort | uniq -c | sort -nr | head -n 109 stress5 /usr/bin/dbus-daemon5 nginx:4 /usr/bin/gjs4 sudo3 /usr/local/uniagentd/bin/uniagentd3 /usr/libexec/gnome-session-binary2 /usr/sbin/xrdp-sesman2 /usr/sbin/xrdp2 /usr/sbin/kerneloops
┌──[root@liruilongs.github.io]-[~] 
└─$

IO 密集型

对于IO 密集型,有两种不同的情况,下面为一个生产环境中 IO 密集型场景通过 mpstat 观测指标,可以看到,用户态(%usr )和内核态(%sys)的 CPU 使用率相对较少,但是CPU 等待IO 完成占比(%iowait) 相对较大,所以整体的CPU空闲率(%idle)较低

┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat -P ALL 1
Linux 4.18.0-477.27.1.el8_8.x86_64 (vms100.liruilongs.github.io)        2024年01月14日  _x86_64_        (4 CPU)
11时43分36秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11时43分37秒  all   12.89    0.00   14.84   50.00    6.25    4.30    0.00    0.00    0.00   11.72
11时43分37秒    0   21.57    0.00   15.69   50.98    5.88    1.96    0.00    0.00    0.00    3.92
11时43分37秒    1   12.68    0.00    9.86   76.06    1.41    0.00    0.00    0.00    0.00    0.00
11时43分37秒    2   12.70    0.00   25.40    3.17   17.46    0.00    0.00    0.00    0.00   41.27
11时43分37秒    3    7.04    0.00    9.86   64.79    1.41   14.08    0.00    0.00    0.00    2.82
.........

stress 模拟负载

当前的系统负载

┌──[root@liruilongs.github.io]-[~] 
└─$uptime 15:15:01 up  1:01,  3 users,  load average: 0.00, 0.09, 0.41
┌──[root@liruilongs.github.io]-[~] 
└─$

模拟命令

┌──[root@liruilongs.github.io]-[~] 
└─$stress --hdd 5 --timeout 600
stress: info: [5778] dispatching hogs: 0 cpu, 0 io, 0 vm, 5 hdd

查看系统平均负载上升

┌──[root@liruilongs.github.io]-[~] 
└─$uptime 15:32:40 up  1:19,  3 users,  load average: 6.10, 5.63, 3.80

观测CPU 性能情况,可以看到,当前空闲率(%idle)较低,CPU使用主要集中在 不可中断IO(%iowait)等待

┌──[root@liruilongs.github.io]-[~] 
└─$mpstat -P ALL 5
Linux 5.15.0-112-generic (liruilongs.github.io) 	2024年08月24日 	_x86_64_	(4 CPU)15时23分21秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
15时23分26秒  all    0.91    0.00    4.21   84.91    0.00    0.11    0.00    0.00    0.00    9.86
15时23分26秒    0    1.25    0.00    4.18   71.82    0.00    0.21    0.00    0.00    0.00   22.55
15时23分26秒    1    0.65    0.00    3.01   92.26    0.00    0.00    0.00    0.00    0.00    4.09
15时23分26秒    2    0.85    0.00    5.33   89.55    0.00    0.00    0.00    0.00    0.00    4.26
15时23分26秒    3    0.86    0.00    4.32   86.39    0.00    0.22    0.00    0.00    0.00    8.21
............
┌──[root@liruilongs.github.io]-[~] 
└─$

通过 vmstat 查看系统整体性能:

CPU 利用率主要集中在内核态和等待 I/O 操作(wa),空闲率较低(id),表明系统正在进行大量的 I/O 操作,系统正在进行大量的磁盘写入操作(bo)

┌──[root@liruilongs.github.io]-[~] 
└─$vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b    交换    空闲    缓冲     缓存   si   so    bi    bo   in   cs us sy id wa st1  6      0 2205568 193376 4205452    0    0    49 30931  945 2194  2  8 81 10  00  6      0 2971176 193388 3439780    0    0     0 354446 1162 1256  1  8 10 81  00  6      0 2769100 193396 3634488    0    0     0 363526 1031 1031  1  8 15 76  00  6      0 2726372 193408 3679292    0    0     0 356962 1034  988  1  8 11 80  01  5      0 2587760 193416 3818884    0    0     0 366231 1052 1100  0  7  7 87  0
c^C

iostat 命令的输出,我们只看到对应的硬盘设备,

据 iostat 命令的输出,可以对系统的 I/O 性能进行以下分析:

  • w_await: 较高的写入等待时间通常意味着磁盘 I/O 压力较大,可能成为系统性能瓶颈,写入平均等待时间为 2.55 - 261.61 ms
  • util: 磁盘利用率为 69.11% - 101.84%
  • aqu-sz: 磁盘的平均请求队列长度,队列长度越长,意味着磁盘 I/O 操作的并行度越高,可能导致更长的等待时间
┌──[root@liruilongs.github.io]-[~] 
└─$iostat  -xk 5 vda
Linux 5.15.0-112-generic (liruilongs.github.io) 	2024年08月24日 	_x86_64_	(4 CPU)avg-cpu:  %user   %nice %system %iowait  %steal   %idle1.58    0.01    7.55   12.14    0.00   78.72Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda              3.84    179.42     1.54  28.60    1.04    46.68 7803.21 128712.72   524.63   6.30    2.55    16.49    0.00      0.00     0.00   0.00    0.00     0.00    2.68    0.07   19.87  69.11avg-cpu:  %user   %nice %system %iowait  %steal   %idle0.63    0.00    3.26   87.69    0.00    8.41Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda              0.00      0.00     0.00   0.00    0.00     0.00  325.40 367139.20     7.00   2.11  217.83  1128.27    0.00      0.00     0.00   0.00    0.00     0.00    0.40    0.50   70.88 100.96avg-cpu:  %user   %nice %system %iowait  %steal   %idle0.68    0.00    9.37   80.69    0.00    9.26Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda              0.00      0.00     0.00   0.00    0.00     0.00  325.80 351251.20    20.20   5.84  261.61  1078.12    0.00      0.00     0.00   0.00    0.00     0.00    0.40    0.00   85.23 101.84^C
┌──[root@liruilongs.github.io]-[~] 
└─$

从以上分析可以得出以下结论:

系统正在进行大量的磁盘写入操作,导致 CPU 资源大量消耗在等待 I/O 操作上。磁盘利用率非常高(%util),接近 100%,表明磁盘可能是系统的瓶颈所在。

实际上这里还有一种情况,这里我们用 fio 进行测试, 通过 fio 异步IO 实际测试发现,虽然平均负载上去了,但是 CPU 等待IO 完成的占比一直上不去,反而是内核态的 CPU 使用率飙升。

fio 测试命令

┌──[root@vms100.liruilongs.github.io]-[~]
└─$fio --name=randwrite --ioengine=libaio --iodepth=1 --rw=randwrite --bs=4K --direct=1 --size=11512M --numjobs=6 --group_reporting --filename=/tmp/testfile

参数说明

  • --ioengine=libaio: 使用 libaio 异步 I/O 引擎进行 I/O 操作。这个引擎可以提高 I/O 并行度。
  • --iodepth=1: 设置 I/O 深度为 1,即每个 I/O 请求同时只有 1 个在处理。
  • --rw=randwrite: 指定 I/O 模式为随机写入。
  • --bs=4K: 设置块大小为 4KB。
  • --direct=1: 使用直接 I/O,绕过文件系统缓存。
  • --size=11512M: 总共要写入的数据量为 11.5GB。
  • --numjobs=6: 启动 6 个并发的写入任务。
  • --group_reporting: 合并输出结果,以便更好地观察整体性能。
  • --filename=/tmp/testfile: 指定写入的文件路径为 /tmp/testfile。

平均负载

┌──[root@liruilongs.github.io]-[~] 
└─$uptime 16:14:51 up  2:01,  3 users,  load average: 4.00, 1.19, 0.83

iostat 输出,可以看到 avgqu-sz 值不是特别大,且请求等待时间 awaitsvctm 所花费时间差距较小,利用率%util为100%, 设备趋于饱和,但是 等待IO 指标体现不明显。 这里的瓶颈实际上在磁盘

┌──[root@vms100.liruilongs.github.io]-[~]
└─$iostat  -dk -x 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io)         2024年08月22日  _x86_64_        (4 CPU)Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.40    1.00 8027.80    54.40 32112.80     8.01     0.07    0.18    0.20    0.18   0.12  99.56Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     3.00    0.00 8068.60     0.00 32352.90     8.02     0.04    0.18    0.00    0.18   0.12  99.62
.......

查看CPU 相关信息,可以看到 使用率大的部分在内核态(%sys),而不是我们希望的 IO 等待(%iowait)

┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat  5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io)         2024年08月22日  _x86_64_        (4 CPU)21时12分46秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
21时12分51秒  all    9.10    0.00   43.52    0.12    0.00    7.89    0.00    0.00    0.00   39.38
21时12分56秒  all    9.52    0.00   42.50    0.18    0.00    8.70    0.00    0.00    0.00   39.11
21时13分01秒  all    7.65    0.00   43.98    0.00    0.00    7.42    0.00    0.00    0.00   40.95
......

这里我换一组参数

┌──[root@liruilongs.github.io]-[~] 
└─$fio --name=seq-read --rw=read --bs=4k --size=1G --numjobs=4 --runtime=6000 --output-format=json

查看平均负载指标上升

┌──[root@liruilongs.github.io]-[~] 
└─$uptime 16:34:28 up  2:20,  3 users,  load average: 1.44, 1.27, 1.85

cpu 性能指标,这时候的指标信息可以看到 CPU 负载主要集中在 等待IO(%iowait),空闲率(%idle)很低,而不是上面的 内核态(%sys)

┌──[root@liruilongs.github.io]-[~] 
└─$mpstat  1 
Linux 5.15.0-112-generic (liruilongs.github.io) 	2024年08月24日 	_x86_64_	(4 CPU)16时33分43秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
16时33分44秒  all    3.55    0.00    5.33   90.10    0.00    0.25    0.00    0.00    0.00    0.76
16时33分45秒  all    6.65    0.00    7.14   84.98    0.00    0.49    0.00    0.00    0.00    0.74
16时33分46秒  all    2.53    0.00    5.82   91.65    0.00    0.00    0.00    0.00    0.00    0.00
16时33分47秒  all    3.79    0.00    5.56   89.14    0.00    0.25    0.00    0.00    0.00    1.26
16时33分48秒  all    7.56    0.00    4.03   71.54    0.00    0.25    0.00    0.00    0.00   16.62

IO 相关指标,磁盘使用率很高,但是IO写入队列不长

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda           2600.00 663552.00     0.00   0.00    2.44   255.21    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    6.34  88.00Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda           1401.00 358400.00     0.00   0.00    5.30   255.82    1.00      4.00     6.00  85.71    2.00     4.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    7.43  97.60Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda           1401.00 358400.00     0.00   0.00    5.37   255.82    2.00     32.00     0.00   0.00  322.50    16.00    0.00      0.00     0.00   0.00    0.00     0.00    2.00    0.00    8.16  93.20

这里有个问题,为什么 fio 模拟IO负载,两次的的指标值不一样?欢迎小伙伴留言讨论 _

  • 第一次平均负载升高原因是 内核态CPU使用率影响
  • 第二次平局负载升高原因是 不可中断IO等待CPU使用率影响

实际上对于 IO 密集型,IO 模式,深度等不同,对平均负载影响也不同,

区别:

I/O 模式:

  • fio --name=randwrite 是随机写入,对 CPU 利用率有较大影响,CPU 主要消耗在内核态处理 I/O 请求。
  • fio --name=seq-read 是顺序读取,对 CPU 消耗相对较小,更多的时间消耗在 I/O 等待上。

I/O 深度:

  • fio --name=randwrite 设置了 iodepth=1,即单个任务的 I/O 深度较浅,需要 CPU 频繁切换上下文。
  • fio --name=seq-read 使用了默认的 I/O 深度,可能会有更多 I/O 请求在队列中等待。

I/O 引擎:

  • fio --name=randwrite 使用了 libaio 异步 I/O 引擎,可以更好地利用多核 CPU 并行处理 I/O。可能产生更高的 I/O 负载和吞吐量
  • fio --name=seq-read 使用了默认的同步 I/O 引擎,对 CPU 的利用率可能不如异步引擎。

关于 Linux 平均负载就可以小伙伴分享到这里,理解不足小伙伴帮忙指正,希望通过对平均负载指标的理解,我们可以快速定位问题。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃


《Linux性能优化》中文版

《BPF Performance Tools》

极客时间 《Linux 性能优化实战》


© 2018-2024 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

这篇关于Linux 性能观测之CPU平均负载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104279

相关文章

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤