平均负载
查看 cpu 个数, 4 核1
2root@imwl01:~# grep 'model name' /proc/cpuinfo |wc -l
4
可以简单理解为 平均活跃进程数 (可运行状态 和 不可中断状态),一般认为 超过 70% 就可以排查 cpu 使用情况。4 核 即为 2.8
可运行状态: 正在使用 CPU 或者正在等待 CPU 的进程,也就是常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态 : 正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程
1 | root@imwl01:~# uptime |
15:45:41 : 当前时间
up 44 min : 开机时间
2 user : 登陆用户数
当前 1分钟 5 分钟 15分钟 很平稳
平均负载升高可能的原因:
- cpu 密集型导致
- I/O 更加繁忙
定法方法
mpstat : 查看 cpu 使用情况 mpstat -P ALL 5 1pidstat : 查看 进程使用情况 pidstat -u 5 1
上下文切换
CPU 寄存器 : CPU 内置的容量小,速度极快的内存
程序寄存器 : 用来存储 CPU 正在执行的指令位置,或者即将执行的下一条指令位置
CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。
而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。
- 进程上下文切换
- 线程上下文切换
- 中断上下文切换
进程上下文切换
进程的运行空间,按 特权等级 分为: 内核空间 和 用户空间
内核空间 ( Ring 0): 可以访问所有资源
用户空间 ( Ring 3): 只能访问受限资源, 不能直接访问内存等硬件设备,需要通过系统调用陷入到内核中,才能访问这些特权资源
进程 在两个空间运行时: 进程的 用户态,内核态
进程上下文切换, 是指从一个进程切换到另一个进程
系统调用一直在同一个进程内运行。发生两次 CPU 上下文切换, 用户态 → 内核态 → 用户态。 通常称为 特权模式切换
系统调用过程通常称为特权模式切换,而不是上下文切换
进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。
从用户态到内核态的转变,需要通过系统调用来完成。
CPU 寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核态代码,CPU 寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。
而系统调用结束后,CPU 寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。所以,一次系统调用的过程,其实是发生了两次 CPU 上下文切换
而系统调用过程中一直是同一个进程在运行。系统调用过程通常称为特权模式切换,而不是上下文切换
进程1 → 保存 进程1 上下文,加载 进程2 上下文 → 进程2
线程上下文切换
线程是调度的基本单位,而进程则是资源拥有的基本单位
当进程只有一个线程时,可以认为进程就等于线程。
当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源。这些资源在上下文切换时是不需要修改的。
另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存的。
因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据
中断上下文切换
中断上下文切换并不涉及到进程的用户态。所以,即便中断过程打断了一个正处在用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。中断上下文,其实只包括内核态中断服务程序执行所必需的状态,包括 CPU 寄存器、内核堆栈、硬件中断参数等
自愿上下文切换和非自愿上下文切换
自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换
vmstat : 分析系统内存使用情况以及 cpu 上下文切换和中断的次数
DMA
Direct Memory Access(DMA)的模块,这个模块允许硬件设备直接通过 DMA 写内存,而不需要通过 CPU(占用 CPU 资源)。
相关总结
自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;
中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。
备注
mpstat
1 | imwl@imwl:~$ mpstat |
() 里为常用缩写
- user : 用户态 CPU 时间,包含 guest ( us )
- nice : 低优先级 (1-19) 用户态CPU 时间。(-20 ~ 19),数值越高,优先级越低 ( ni )
- system : 内核态 CPU 时间 (sy)
- idle : 空闲时间。不包括等待 I/O 的时间 ( id )
- iowait : 等待 I/O 的 CPU 时间 ( wa )
- irq : 处理硬中断的 CPU 时间 ( hi )
- softirq : 处理软中断的 CPU 时间 ( si )
- steal : 当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间 ( st )
- guest : 代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间 ( guset )
10.guest_nice : 以低优先级运行虚拟机的时间 ( gnice )
cpu 使用率 = 1 - 空闲时间/总cpu时间
pidstat
1 | imwl@imwl:~$ pidstat |
UID : 用户ID
PID : 进程识别号
PPID : 当前进程的父进程 ID
vmstat
1 | [root@test-1 ~]# vmstat |