1. pidstat+mpstat详解进阶
1.1. pidstat(局部)
pidstat -w
进程上下文切换情况,显示各活动进程的上下文切换情况统计
- cswch/s 每秒自愿上下文切换 (voluntary context switches) 的次数
-
- 进程获取不了所需要的资源导致的上下文切换
- 比如 出现 I/O 问题瓶颈、内存等系统资源不足,会发生自愿上下文切换
- nvcswch/s 每秒非自愿上下文切换 (non voluntary context switches) 的次数
-
- 进程由于调度算法,时间片已到等原因,被系统【强制调度】发生上下文切换
- 比如大量进程再抢夺 CPU 资源时,会发生非自愿上下文切换,CPU 出现了瓶颈
pidstat -t -p pid
显示进程里面的线程的统计信息
字段 |
说明 |
PID |
进程 ID |
cswch/s |
每秒自愿上下文切换 (voluntary context switches) 的次数 |
nvcswch/s |
每秒非自愿上下文切换 (non voluntary context switches) 的次数 |
Command |
当前进程对应的命令 |
pidstat -wt 1
组合命令,看具体进程里面的线程上下文切换情况
字段 |
说明 |
TGID |
主线程 ID |
TID |
线程 id |
%usr |
进程在用户空间占用 cpu 的百分比 |
%system |
进程在内核空间占用 cpu 的百分比 |
%guest |
进程在虚拟机占用 cpu 的百分比,(基本很少用) |
%CPU |
进程占用 cpu 的百分比 |
CPU |
处理进程的 cpu 编号 |
Command |
当前进程对应的命令 |
1.2. vmstat(全局)
全称是 Virtual Memory Statistics(虚拟内存统计)的缩写,是对系统整体的情况进行统计,不细化到某个进程,是宏观命令
格式:vmstat [选项] [时间间隔] [次数]
(参数很多,记住常用的即可)
vmstat n
每隔n
秒后输出一行信息,一般会加个-w
进行加宽显示,比如vmstat -w 1
vmstat -SM
指定单位显示,默认 KB,M 表示是 MBvmstat -t
带上时间戳信息- 更多参数信息
vmstat -h
或man vmstat
实时查看系统 CPU 的队列情况、内存、块 I/O、上下文切换情况、系统中断数、cpu 使用率等
- 和
mpstat
命令有交集,都是可以看出 cpu 使用率,在内核态、用户态等
#用户态占比高
stress --cpu 8 --timeout 600s
#内核态占比高
stress --io 8 --timeout 600s
- Linux 里面很多分析工具都是有交集的,但主要用途有差别
上下文切换和中断的合理范围:没给 CPU 负载的时候也有每秒 1 万次内,不过也取决 cpu 的性能
字段 |
说明 |
r |
r(running or runnable)就绪队列的长度,包括正在运行和等待 CPU 的进程数 |
b |
b(Blocked)处于不可中断睡眠状态的进程数, 或者 即可产生 |
swpd |
虚拟内存使用情况,单位 KB |
free |
空闲内存空间,单位 KB |
buff |
缓冲的内存空间,单位 KB |
cache |
缓存的内存空间,单位 KB |
si |
从磁盘中交换至内存的数据量,单位 KB,数值越大代表内存和磁盘之间的转换越频繁,系统的性能越差 |
so |
从内存中交换到磁盘中的数据量,单位 KB,数值越大代表内存和磁盘之间的转换越频繁,系统的性能越差 |
bi |
从块设备中读入的数据的总量,单位是块,值越大代表系统的 I/O 越繁忙 |
bo |
写到块设备的数据的总量,单位是块,值越大代表系统的 I/O 越繁忙 |
in |
(interrupt) 每秒中断的次数 |
cs |
(context switch) 每秒上下文切换次数,会浪费较多的 cpu 资源,比如我们调用系统函数,数值应该越小越好 |
us |
在用户态进程所使用 CPU 时间的百分比,CPU 使用率 |
sy |
在内核态进程所使用 CPU 时间的百分比,CPU 使用率 |
id |
空闲 CPU 的百分比,在 linux 2.5.41 之前,这部分包含 IO 等待时间 |
wa |
等待 I/O 的 CPU 时间百分比 |
st |
被虚拟机所盗用的 CPU 百分比(基本很少用) |
2. cpu 的上下文切换知识点回顾
cpu 寄存器和程序计数器是 cpu 在运行任务前依赖的环境,也叫 cpu 上下文
cpu 的上下文切换把上一个任务的 cpu 上下文保存起来【下次才知道任务从哪里加载 + 运行】再加载新任务的上下文到寄存器和程序计数器进行运行任务,每次切换在【保存和恢复】上下文耗时几十纳秒 或 微秒
再加上下文切换 = 1000000ns【纳秒】=1000us【微秒】=1000ms【毫秒】
cpu 的上下文切换的场景
- 【系统调用切换】
-
- 即内核态和用户态的切换,一直是同一个进程在运行,不切换进程
- 一次系统调用的过程发生两次 cpu 上下文切换,切换过去,切换回来
- 【进程上下文切换】
-
- 每个 cpu 都维护了一个就绪队列,存放活跃进程,根据情况进行调度
- 进程是由内核来管理和调度的,进程的切换只能发生在【内核态】
- 比如你用【网易云听着歌、玩着英雄联盟】因为现在电脑多 CPU 多核心配置好,所以你感觉不到切换
- 【线程上下文切换】
-
- 进程是资源拥有的基本单位,线程是调度的基本单位,当进程只有一个线程的时候,可以认为进程就等于线程
- 前后线程同属于一个进程,切换时虚拟内存资源不变
- 上下文切换时需要保存的是线程私有数据,比如栈和寄存器
- 同进程内的线程切换,要比多进程间的切换消耗更少的资源,所以开发中用多线程代替多进程的原因
- 【中断上下文切换】
-
- 快速响应硬件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件
- 打断其他进程时,就需要保存该进程状态,这样在设备事件结束后,就可以从原来的状态恢复
- 比如老王挪了下鼠标,按了下键盘,CPU 就必须中断正在执行的程序,转而去响应这些硬件的事件
sysbench
- 是一款开源的多线程性能测试工具,模拟线程上下文切换过多场景等
- 可以执行 CPU / 内存 / 线程 / I/O/ 数据库等方面的性能测试
- 常用命令
-
sysbench --threads=32 --time=300 threads run
32 个线程持续运行 5 分钟,多线程压测
3. 综合实战
3.1. 大量线程进行上下文切换,导致平均负载升高,CPU 使用率也会比较高,系统是 4 核
- 终端一:模拟 32 个线程进行压测,持续 300s
sysbench --threads=32 --time=300 threads run
- 终端二:
-d
参数表示高亮显示变化的区域watch -d uptime
- 终端三:
vmstat -w 1
查看系统 CPU 的队列情况、内存、块 I/O、上下文切换情况、系统中断次数、cpu 使用率等
-
- 和
mpstat
命令有交集,都是可以看出 cpu 使用率,在内核态、用户态等
- 和
- 终端四:
pidstat -w
查看运行中的进程和任务上下文切换情况统计,显示各活动进程的上下文切换情况统计
-
pidstat -t -p pid
显示进程里面的线程的统计信息pidstat -wt 1
组合命令,查看进程里面具体线程的上下文切换情况
宏观思路
- 先看全局,找系统哪个资源问题,是 CPU 还是 IO 还是啥瓶颈
- 知道具体后,再看啥哪个进程导致的这个资源有问题
详细分析思路
- 全局
-
uptime
(全局):运行 1 分钟后,4 个核的 CPU 负载是比较高mpstat
(全局):
-
-
- 应用场景:当系统变慢,CPU 平均负载增大时,判断是 CPU 的使用率增大,还是 IO 压力增大的情况导致
- 多次调用
mpstat -P ALL 2 2
,持续观察,每个 cpu 利用率都高,使用率接近 100%,iowait 很低接近 0,IO 不是瓶颈
-
线程一
线程二
线程三
线程四
- 局部
-
- 通过
pidstat -u 2 2
对进程和任务使用情况进行分析,发现 CPU 使用率接近 100%,原因是大量上下文切换。 - 利用
pidstat -wt 2 2
查看哪个进程大量占据上下文切换,进而深入进程内具体线程,大量上下文切换会导致负载变高。 pidstat
还有其他功能:pidstat -u
查看 CPU 情况;pidstat -d
查看磁盘 I/O 情况;pidstat -t
显示进程内线程的统计信息;pidstat -w
查看进程上下文切换情况,以确定哪种上下文切换占比高。若没加-t
,显示的是进程上下文切换,与vmstat
数据不同,可推断是进程内部大量线程切换导致;加-t
发现nvcswch
高,即大量线程抢夺 CPU 资源导致问题。
- 通过
4. top-mpstat-pidstat中wait含义
- top 中的 wa:表示等待 I/O 完成的时间,等待的 I/O 分为网络和磁盘两类,需进一步分析。
- mpstat 中的 % iowait:展示 CPU 或 CPUs 处于空闲且系统有未完成磁盘 I/O 请求时的时间占比,等待的 I/O 有网络和磁盘两类,需进一步分析。
- vmstat 中的 wa:是等待 I/O 所花费的时间,在 Linux 2.5.41 之前,该时间包含在空闲时间里,等待的 I/O 分网络和磁盘两类,需进一步分析。
- pidstat 中的 % wait(10.1.5 版本的 pidstat 看不到 % wait 列,11.1.1 版本可看到,可通过
pidstat -V
查看版本):表示任务等待运行时占用 CPU 的时间百分比,即进程等待 CPU 分配的时间占比。
总结:
- 等待CPU的进程在CPU的就绪队列中,处于运行状态
- 等待IO的进程则处于不可中断状态,有磁盘IO,网络IO