平均负载

平均负载是指单位时间内,系统处于 可运行状态 和 不可中断状态 的平均进程数。简单理解,就是平均活跃进程数

  • 可运行状态:进程正在或等待使用CPU
  • 不可中断状态:进程正在等待硬件设备的I/O,是系统对进程和硬件设备的一种保护机制。

最理想的情况是,每个CPU上刚好运行着1个进程,也就是平均负载等于CPU的个数。假如平均负载是2,那么意味着:

  • 单核CPU上,有一半的进程竞争不到CPU
  • 双核CPU上,所有的CPU刚好被完全占用
  • 4核CPU上,意味着CPU有50%的空闲(idle)

注意,这里的核指逻辑核数,比如超线程的双核CPU,相当于4核。

因此,当平均负载比CPU个数还大时,就出现了系统过载。

在生产环境中,一般推荐平均负载不要高于CPU数量的70%

区别CPU使用率

CPU使用率是单位时间内CPU繁忙情况的统计。而平均负载包括正在使用CPU、等待CPU、等待IO的进程。具体来说:

  • CPU密集型进程,CPU使用率高,平均负载高
  • I/O密集型进程,平均负载高,CPU使用率低
  • 大量等待CPU的进程,平均负载高,CPU使用率也会比较高

案例分析

准备工具

linux系统,并安装以下两款工具:yum install stress sysstat

  • stress: linux系统压力测试工具
  • sysstat:包含了常用的linux性能工具,这里用到它提供的两个命令:
    • mpstat: 多核CPU性能分析工具
    • pidstat: 进程性能分析工具,可实时查看cpu, 内存,I/O以及上下文切换等指标

场景一:CPU密集型进程

以root身份登录中断,在终端1执行如下命令:

stress --cpu 2 --timeout 600
# 产生2个进程,压测CPU 600秒, 具体命令参考 man stress说明

终端2执行uptime查看平均负载的变化情况

# watch 监测 -d 表示高亮显示变化的部分
watch -d uptimeEvery 2.0s: uptime                                                               Wed Dec 26 20:39:47 201820:39:47 up 54 days,  2:56,  4 users,  load average: 0.93, 4.30, 3.23

终端3查看CPU使用率变化:

mpstat -P ALL 2 5
# 每两秒刷新下所有CPU的统计报告,一共刷新显示显示5次。如果不指定最后一个5,那么将一直刷新。
mpstat -P ALL 2
Linux 3.10.0-693.11.1.el7.x86_64 (iz2zeap40j01vg100ifsf4z)      12/26/2018      _x86_64_        (2 CPU)08:41:38 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
08:41:43 PM  all   33.56    0.00    2.01    0.00    0.00    0.00    0.00    0.00    0.00   64.43
08:41:43 PM    0   17.37    0.00    1.27    0.00    0.00    0.00    0.00    0.00    0.00   81.36
08:41:43 PM    1   92.19    0.00    6.25    0.00    0.00    0.00    0.00    0.00    0.00    1.56# 其中一个CPU的使用率非常高, 但iowait为0,说明平均负载的升高是由CPU使用率高造成的。

使用查看导致CPU升高的进程:

pidstat -u 2 1
# -u 报告CPU的使用率,2 每两秒,1 报告一次
07:57:34 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:57:39 PM     0         9    0.00    0.20    0.00    0.20     1  rcu_sched
07:57:39 PM     0       479  100.00    0.00    0.00  100.00     0  stress
07:57:39 PM     0      1586    0.00    0.20    0.00    0.20     0  aliyun-service

场景二:I/O 密集型进程

stress --io N --timeout 600
# 产生N个进程,模拟IO压力

场景三:大量进程的情况

stress --cpu 8  # 产生8个进程对CPU进行压测

由于系统只有两个CPU,因此系统处于严重过载状态:

uptime查看负载:1分钟平均负载慢慢飙升到 8.97

20:36:39 up 62 days,  2:53,  5 users,  load average: 8.97, 5.49, 2.86

mpstat查看CPU统计数据,可以看到CPU 0 和 1 都满了

Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
Average:       0   98.96    0.00    0.52    0.00    0.00    0.52    0.00    0.00    0.00    0.00
Average:       1  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00

pidstat 查看系统任务统计(一个任务相当于一个进程)

Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:        0      1286    0.49    0.00    0.00    0.49     -  java
Average:        0      3270   23.15    0.00    0.00   23.15     -  stress
Average:        0      3271   25.62    0.00    0.00   25.62     -  stress
Average:        0      3272   23.65    0.00    0.00   23.65     -  stress
Average:        0      3273   27.09    0.00    0.00   27.09     -  stress
Average:        0      3274   25.12    0.00    0.00   25.12     -  stress
Average:        0      3275   21.67    0.00    0.00   21.67     -  stress
Average:        0      3276   25.62    0.00    0.00   25.62     -  stress
Average:        0      3277   23.15    0.00    0.00   23.15     -  stress
Average:        0      6453    0.49    0.00    0.00    0.49     -  dockerd
Average:        0     30783    0.00    0.49    0.00    0.49     -  celery

CPU上下文切换

当活跃进程数大于CPU数量时,会出现竞争,CPU需要轮流执行这些进程,于是产生CPU上下文切换,这个切换是有开销的,会导致负载升高。

查看CPU上下文切换

vmstat 用来查看虚拟内存,也可以查看一些CPU总体的上下文切换情况。

vmstat 5 1
# 5秒钟输出一组数据
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st1  0      0 124980 170900 1002128    0    0    22    14    1    1  2  1 97  0  00  0      0 124740 170900 1002144    0    0     0  1820 1074 1195  2  1 97  0  0

有用参数

  • cs: context switch 每秒钟上下文切换次数
  • in:interrupt 每秒钟系统中断次数
  • r:running or runnable 就绪队列的长度(运行中,等待运行的进程数)
  • b:blocked 处于不可中断的进程数(进程正在等待硬件设备的I/O)

使用pidstat -w查看每个进程的详细情况:

pidstat -w 5Average:      UID       PID   cswch/s nvcswch/s  Command
Average:        0         3      0.40      0.00  ksoftirqd/0
Average:        0         9     57.49      0.00  rcu_sched
Average:        0        10      0.20      0.00  watchdog/0

参数:

  • cswch/s:voluntary context switches 自愿上下文切换,指进程无法获取所需的自愿(I/O, 内存等系统资源不足时),发生自愿的上下文切换。
  • nvcswch/s: non voluntary context switches 非自愿的上下文切换,进程的时间片到期,被系统强制发生的切换。当大量进程争抢CPU时,就会发生非自愿的上下文切换

模拟测试

安装sysbench,多线程基准测试工具:yum install sysbench sysstat

输入如下命令模拟系统多线程调度的瓶颈:

sysbench --threads=10 --max-time=300 threads run
# 运行10个线程,5分钟

新开一个终端,查看上下文切换情况:

vmstat 1 1 # 每秒刷新一次procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st9  0      0 296684 171112 1201540    0    0    21    14    2    2  2  1 97  0  06  0      0 296560 171112 1201540    0    0     0     0 3081 1947126 12 88  0  0  06  0      0 296436 171112 1201540    0    0     0     0 3192 2086130 14 86  1  0  0

可以发现如下特点:

  • r 就绪队列,长度达到9,超过系统CPU个数(2个)
  • in 终端次数达到3000次
  • cs 上下文切换次数达到每秒200万次
  • us + sy 的cpu使用率加起来达到100%,其中几乎都被sys占用,说明CPU主要被内核占用了

综合以上数据,得出结论:系统的就绪队列过长,导致了大量的上下文切换,大量上下文切换又导致了CPU的占用率升高。

下面我们通过pidstat命令来查看具体情况:

pidstat -wu 1 2
# -w 输出切换指标  -u 输出CPU使用率  1秒刷新一次,一共刷新2次08:58:30 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
08:58:31 PM     0      1286    1.00    0.00    0.00    1.00     1  java
08:58:31 PM     0      3871    1.00    1.00    0.00    2.00     1  AliYunDun
08:58:31 PM   999      7145    1.00    0.00    0.00    1.00     1  redis-server
08:58:31 PM     0      9626    1.00    0.00    0.00    1.00     1  celery
08:58:31 PM     0      9627    1.00    0.00    0.00    1.00     0  celery
08:58:31 PM     0     11201   31.00  100.00    0.00  100.00     1  sysbench  # 100% CPU08:58:30 PM   UID       PID   cswch/s nvcswch/s  Command
08:58:31 PM     0         9     65.00      0.00  rcu_sched
08:58:31 PM     0        13      2.00      0.00  ksoftirqd/1
08:58:31 PM     0       266      3.00      0.00  kworker/0:1H
08:58:31 PM     0       271      4.00      0.00  jbd2/vda1-8
08:58:31 PM     0      1267     10.00      0.00  wrapper
08:58:31 PM     0      1439     12.00      0.00  PM2
# ...08:58:31 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
08:58:32 PM     0     11201   30.00  100.00    0.00  100.00     1  sysbench
08:58:32 PM     0     11213    0.00    1.00    0.00    1.00     1  pidstat08:58:31 PM   UID       PID   cswch/s nvcswch/s  Command
08:58:32 PM     0         9     58.00      0.00  rcu_sched
08:58:32 PM     0        13      1.00      0.00  ksoftirqd/1
08:58:32 PM     0       482      1.00      0.00  irqbalance
08:58:32 PM     0      1267     10.00      0.00  wrapper
08:58:32 PM     0      1439     12.00      0.00  PM2
# ...

观察输出,发现sysbench确实导致了CPU使用率升高,但是上下文切换来自其他进程,并且数量加起来都不到3位数,那为什么vmstat中观察到了200万了,这是为什么?

这是因为线程是系统调度的基本单位,而且sysbench模拟的是线程调度。因此,只需加一个-t参数,就可以查看线程切换了:

pidstat -wut 1 309:09:18 PM   UID      TGID       TID    %usr %system  %guest    %CPU   CPU  Command
09:09:19 PM     0      1267         -    1.00    0.00    0.00    1.00     1  wrapper
09:09:19 PM     0         -      3818    1.00    0.00    0.00    1.00     0  |__AliYunDunUpdate
09:09:19 PM     0         -      3872    1.00    0.00    0.00    1.00     0  |__AliYunDun
09:09:19 PM     0     11290         -   34.00  100.00    0.00  100.00     1  sysbench
09:09:19 PM     0         -     11291    4.00   15.00    0.00   19.00     0  |__sysbench
09:09:19 PM     0         -     11292    3.00   16.00    0.00   19.00     1  |__sysbench
09:09:19 PM     0         -     11293    3.00   15.00    0.00   18.00     1  |__sysbench
09:09:19 PM     0         -     11294    3.00   14.00    0.00   17.00     0  |__sysbench
09:09:19 PM     0         -     11295    3.00   17.00    0.00   20.00     0  |__sysbench
09:09:19 PM     0         -     11296    4.00   19.00    0.00   23.00     0  |__sysbench
09:09:19 PM     0         -     11297    3.00   16.00    0.00   19.00     0  |__sysbench
09:09:19 PM     0         -     11298    4.00   16.00    0.00   20.00     0  |__sysbench
09:09:19 PM     0         -     11299    3.00   15.00    0.00   18.00     0  |__sysbench
09:09:19 PM     0         -     11300    3.00   15.00    0.00   18.00     0  |__sysbench
09:09:19 PM     0     11302         -    0.00    1.00    0.00    1.00     1  pidstat
09:09:19 PM     0         -     11302    0.00    1.00    0.00    1.00     1  |__pidstat09:09:18 PM   UID      TGID       TID   cswch/s nvcswch/s  Command
# ...
09:09:19 PM     0      9631         -      5.00      0.00  celery
09:09:19 PM     0         -      9631      5.00      0.00  |__celery
09:09:19 PM     0         -      9668      2.00      0.00  |__celery
09:09:19 PM     0         -      9669      2.00      0.00  |__celery
09:09:19 PM     0      9632         -      4.00      0.00  celery
09:09:19 PM     0         -      9632      4.00      0.00  |__celery
09:09:19 PM     0         -      9674      2.00      0.00  |__celery
09:09:19 PM     0         -      9675      2.00      0.00  |__celery
09:09:19 PM     0     11267         -      1.00      0.00  kworker/1:1
09:09:19 PM     0         -     11267      1.00      0.00  |__kworker/1:1
09:09:19 PM     0         -     11291  22986.00 175294.00  |__sysbench
09:09:19 PM     0         -     11292  28215.00 170894.00  |__sysbench
09:09:19 PM     0         -     11293  23272.00 138182.00  |__sysbench
09:09:19 PM     0         -     11294  34244.00 151715.00  |__sysbench
09:09:19 PM     0         -     11295  31714.00 167521.00  |__sysbench
09:09:19 PM     0         -     11296  20949.00 194500.00  |__sysbench
09:09:19 PM     0         -     11297  30983.00 185232.00  |__sysbench
09:09:19 PM     0         -     11298  28358.00 172171.00  |__sysbench
09:09:19 PM     0         -     11299  29662.00 159875.00  |__sysbench
09:09:19 PM     0         -     11300  27557.00 148900.00  |__sysbench
09:09:19 PM     0     11302         -      2.00      4.00  pidstat
09:09:19 PM     0         -     11302      2.00      4.00  |__pidstat
# ...

从上述输出可以观察到,sysbench的线程的大量切换。

另外,如果要查看中断次数,可以读取这个文件/proc/interrupts

/proc 实际上是 Linux 的一个虚拟文件系统,用于内核空间与用户空间之间的通信。/proc/interrupts 就是这种通信机制的一部分,提供了一个只读的中断使用情况。

watch -d cat /proc/interrupts
# 高亮显示中断文件的变动部分Every 2.0s: cat /proc/interrupts                                        Thu Jan 10 21:20:13 2019CPU0       CPU10:         20          0   IO-APIC-edge      timer1:         10          0   IO-APIC-edge      i80426:          3          0   IO-APIC-edge      floppy8:          0          0   IO-APIC-edge      rtc09:          0          0   IO-APIC-fasteoi   acpi10:          0          0   IO-APIC-fasteoi   virtio411:         35          0   IO-APIC-fasteoi   uhci_hcd:usb112:         15          0   IO-APIC-edge      i804214:          0          0   IO-APIC-edge      ata_piix15:    5756484          0   IO-APIC-edge      ata_piix24:          0          0   PCI-MSI-edge      virtio2-config25:    2673089    5845758   PCI-MSI-edge      virtio2-req.026:          1          0   PCI-MSI-edge      virtio0-config27:    1868713   37408103   PCI-MSI-edge      virtio0-input.028:     349576   44643775   PCI-MSI-edge      virtio0-output.029:          0          0   PCI-MSI-edge      virtio3-config30:     326128          0   PCI-MSI-edge      virtio3-req.031:          0          0   PCI-MSI-edge      virtio1-config32:         22          0   PCI-MSI-edge      virtio1-virtqueues
NMI:          0          0   Non-maskable interrupts
LOC: 2924265642 2872116981   Local timer interrupts
SPU:          0          0   Spurious interrupts
PMI:          0          0   Performance monitoring interrupts
IWI:   60559294   62135237   IRQ work interrupts
RTR:          0          0   APIC ICR read retries
RES:  296793417  297917656   Rescheduling interrupts
CAL:   18746994     956271   Function call interrupts
TLB:    5927981    5878741   TLB shootdowns
TRM:          0          0   Thermal event interrupts
THR:          0          0   Threshold APIC interrupts
DFR:          0          0   Deferred Error APIC interrupts
MCE:          0          0   Machine check exceptions

从中可以观察到,以下两个参数在不断变化

  • Local timer interrupts
  • Rescheduling interrupts 重新调度中断(RES),表示唤醒空闲状态的CPU来调度新的任务运行,这是多处理器系统中,调度器用来分散任务到不同CPU的机制

结论

每秒上下文切换次数的大小,取决于CPU性能,一般来说,切换稳定,数值从百到万以内,都算正常:

  • cswch/s 切换多,说明进程在等待资源,可能发生了I/O等其他问题
  • nvcswch/sq 切换多,说明进程被强制调度,也就是争抢CPU,说明CPU有瓶颈
  • 中断次数多了,说明CPU被中断程序占用,具体可以分析 /proc/interrupts文件

平均负载及CPU上下文切换相关推荐

  1. 平均负载与 CPU 使用率

    一.什么是平均负载 正确定义:单位时间内,系统中处于可运行状态和不可中断状态的平均进程数. 错误定义:单位时间内的cpu使用率. 可运行状态的进程:正在使用cpu或者正在等待cpu的进程,即ps au ...

  2. 1、cpu平均负载和cpu使用率 排查cpu使用高问题

    自定义标题 1. CPU 2. CPU 使用率 3. 测试: 4. 总结 1. CPU cpu平均负载 uptime 或 top 查看 cpu 平均负载(平均负载是指单位时间内,系统处于可运行状态和不 ...

  3. 理解Linux系统平均负载和CPU使用率

    CPU 使用率 CPU 使用率就是 CPU 非空闲态运行的时间占比,它反映了 CPU 的繁忙程度.比如,单核 CPU 1s 内非空闲态运行时间为 0.8s,那么它的 CPU 使用率就是 80%:双核 ...

  4. 【Linux 性能优化系列】Linux 性能优化 -- CPU 性能篇(一) 平均负载、上下文切换、CPU 使用率

    [Linux 性能优化系列]Linux 性能优化 -- CPU 性能篇(一) 平均负载.上下文切换.CPU 使用率 [1]相关概念 [1.1]平均负载 平均负载是指单位时间内,系统处于可运行状态和不可 ...

  5. linux cpu平均负载,关于linux系统CPU篇---平均负载

    1.什么是平均负载?(load average) 平均负载是指单位时间内平均活跃进程数,包括可运行状态的进程数,以及不可中断状态的进程(如等待IO,等待硬件设备响应) 2.如何查看平均负载? 使用to ...

  6. Linux性能优化一:CPU优化以及平均负载的理解

    文章目录 前言: 什么是系统性能调优 到底怎么理解平均负载 它和CPU使用率的关系 平均负载多少合适 如何分析平均负载 平均负载升高的实战模拟 场景:CPU密集型进程 场景二:I/O密集型程序 前言: ...

  7. 02丨基础篇:到底应该怎么理解“平均负载”?

    每次发现系统变慢时,我们通常做的第一件事,就是执行 top 或者 uptime 命令,来了解系统的负载情况.比如像下面这样,我在命令行里输入了 uptime 命令,系统也随即给出了结果. $ upti ...

  8. 1 理解Linux系统的“平均负载”

    什么是平均负载 我们知道使用top或uptime可以用来了解系统的负载情况. uptime 2 02:34:03 up 2 days, 20:14, 1 user, load average: 0.6 ...

  9. 项目实战,平均负载过高,最后发现却是这个搞鬼

    1.前言 最近在项目上遇到负载均衡过高的问题,分析好几天,还因此移植了一个CPU检测工具,后面在小二哥的指导找到了问题原因,小二哥有些读者应该会比较熟悉,之前发的微信滑动卡顿就是他分析的,他是一个非常 ...

最新文章

  1. Ubuntu下配置Nginx HTTPS
  2. 全球首个「活体机器人」生娃!100%青蛙基因,杀不死,可繁衍4世
  3. Odoo之Field
  4. java tcp read_【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)...
  5. python注释可以辅助程序调试吗_Python 注释
  6. codeforces1498 D. Bananas in a Microwave(背包+优化)
  7. excel连接mysql 数据库
  8. linux内核head.S文件分析
  9. SingToken全球首款区块链智能AI音乐钱包
  10. 内存降价-可以入手啦
  11. java中mysql.ini_为什么找不到mysql.ini文件,我是放在scr目录下的
  12. 数字电子技术基础-2-逻辑函数的最小项与最大项
  13. 【数论】范数(norm)
  14. webp格式图片如何简单快速转换成JPG、PNG格式
  15. android 修改手机型号加点,修改Android设备信息,如修改手机型号为iPhone7黄金土豪版! -电脑资料...
  16. 照片太大怎么缩小kb?
  17. 终极文件/文件夹隐藏方案大全
  18. 微信小程序开发账号找回
  19. Combined Cycle Power Plant Data Set(初学练手:详解)
  20. Java生成word文档|综合

热门文章

  1. QT 线程池 + TCP 小试(二)实现通信功能
  2. 简单工厂模式、工厂方法模式、抽象工厂模式
  3. Ubuntu更换国内源(apt更换源)
  4. js 图片压缩上传(base64位)以及上传类型分类
  5. CSS进阶(十)position:relative
  6. Python-OpenCV快速教程
  7. 进程与multiprocessing模块
  8. 【转】【Linux】sed命令详解
  9. Android开发学习笔记--一个有界面A+B的计算器
  10. 35岁小贝荣膺终身成就奖