Code前端首页关于Code前端联系我们

Linux性能优化:如何理解“负载平均”?什么是合理的平均负载?

terry 2年前 (2023-09-28) 阅读数 63 #未命名

如何理解“平均负载”

平均负载:单位时间内系统中平均处于运行状态和不间断状态的进程数,即平均活跃进程数。它与我们传统理解的 CPU 使用率没有直接关系。 不可中断进程是处于内核态关键进程的进程(例如等待设备的公共 I/O 响应)。不间断状态实际上是系统对进程和硬件设备的一种保护机制。

合理的平均负载是多少?

监控中将系统在当前生产环境下的平均负载,根据历史数据判断负载变化趋势。如果暴露量有明显上升趋势,应及时进行分析调查。当然,你也可以设置一个阈值(比如平均负载高于CPU数量的70%时)在实际工作中,我们经常混淆平均负载和CPU使用率的概念。其实两者并不完全等价:
  • CPU密集型进程,大量的CPU使用会增加平均负载,此时两者是一致的
  • I/O密集型进程,等待I/O 也会增加平均负载,CPU 使用率不一定很高,此时都比较高
如果平均负载高,可能是 CPU 密集型进程造成的,也可能是由繁忙的 I/O 引起。具体分析时,可以使用mpstat/pidstat工具来帮助分析负载源。

CPU

CPU 上下文切换(第 1 部分)

CPU 上下文切换就是保存上一个任务的 CPU 上下文(CPU 寄存器和 PC),然后将新任务的上下文加载到这些寄存器中,程序计数器。最后跳转到程序计数器指示的位置并运行新任务。其中,保存的上下文存储在系统内核中,并在任务重新调度执行时重新加载,以保证原来的任务状态不受影响。

根据任务类型,CPU上下文切换分为:

  • 进程上下文切换
  • 线程上下文切换
  • 中断上下文 根据权限级别切换进程的运行空间 分为内核空间和用户空间。从用户态到内核态的转换必须通过系统调用来完成。

    一个系统调用过程实际上会进行两次CPU上下文切换:

    • 首先保存CPU寄存器中的用户态指令位置,将CPU寄存器更新为内核态指令位置并跳转到内核态运行内核任务;
    • 系统调用完成后,CPU寄存器恢复原来存储的用户态数据,然后切换到用户空间继续运行。

    系统调用过程不涉及虚拟内存等进程用户态资源,也不涉及进程切换。它与传统意义上的进程上下文切换不同。这就是为什么系统调用通常被称为特权模式切换。

    进程由内核管理和调度,进程上下文切换只能发生在内核态。因此,相比于系统调用,内核在保存当前进程的状态和CPU寄存器之前,必须先保存进程的虚拟内存和堆栈。新进程的内核态加载后,必须刷新进程的虚拟内存和用户堆栈。

    进程仅在计划在CPU上运行时才需要切换上下文。有以下场景:CPU时间片交替分配、系统资源不足导致进程挂起、进程因sleep功能主动挂起、高优先级进程抢占时间片、发生硬件中断时,进程CPU 被挂起,转而执行内核中的中断服务。

    线程上下文切换

    线程上下文切换分为两种:

    • 前、后线程属于同一个进程。切换过程中虚拟内存资源保持不变。只需要改变线程的私有数据、寄存器等;线程属于不同的进程,与进程上下文切换相同。

    同一进程内的线程切换消耗的资源较少,这也是多线程的优点。

    中断上下文切换

    中断上下文切换不包括进程的用户态,因此中断上下文只包含内核态中断服务程序执行所必需的状态(CPU寄存器、内核堆栈、硬件中断)参数等)。

    中断处理优先级高于进程,因此中断上下文切换和进程上下文切换不会同时发生。第二个

  • r (正在运行或正在运行) 完成队列的长度,正在运行并等待 d'CPU 的进程数量
  • b (阻塞) 处于不可用状态 中断睡眠状态的进程数量

To查看每个进程的详细信息,必须使用 pidstat 来查看每个进程的上下文切换

pidstat -w 514时51分16秒   UID       PID   cswch/s nvcswch/s  Command14时51分21秒     0         1      0.80      0.00  systemd14时51分21秒     0         6      1.40      0.00  ksoftirqd/014时51分21秒     0         9     32.67      0.00  rcu_sched14时51分21秒     0        11      0.40      0.00  watchdog/014时51分21秒     0        32      0.20      0.00  khugepaged14时51分21秒     0       271      0.20      0.00  jbd2/vda1-814时51分21秒     0      1332      0.20      0.00  argusagent14时51分21秒     0      5265     10.02      0.00  AliSecGuard14时51分21秒     0      7439      7.82      0.00  kworker/0:214时51分21秒     0      7906      0.20      0.00  pidstat14时51分21秒     0      8346      0.20      0.00  sshd14时51分21秒     0     20654      9.82      0.00  AliYunDun14时51分21秒     0     25766      0.20      0.00  kworker/u2:114时51分21秒     0     28603      1.00      0.00  python3
  • cswch 每秒自愿上下文切换的次数(进程无法获取所需资源引起的上下文切换)
  • nvcswch 每秒自愿上下文切换的次数每秒非自愿上下文切换(轮换时间片和其他系统强制调度)
vmstat 1 1    #新终端观察上下文切换情况此时发现cs数据明显升高,同时观察其他指标:r列:远超系统CPU个数,说明存在大量CPU竞争us和sy列:sy列占比80%,说明CPU主要被内核占用in列:中断次数明显上升,说明中断处理也是潜在问题
表示 CPU 上运行/等待的进程过多,导致大量上下文切换。上下文切换导致系统CPU占用率高。
pidstat -w -u 1  #查看到底哪个进程导致的问题

从结果可以看出,sysbench导致CPU使用率过高,但pidstat输出的上下文总数并不高。分析sysbench模拟线程切换,所以需要在pidstat后面添加-t参数才能看到线程指标。 另外,如果中断太多,我们可以通过/proc/interrupts文件读取

watch -d cat /proc/interrupts

发现变化最快的数字是重新调度中断(RES),它是用来唤醒空闲CPU的安排新任务。分析仍然是由于任务过多的调度问题,这与上下文切换分析是一致的。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门