我们来说一下,如何查看系统的上下文切换情况
过多的上下文切换,会将CPU时间消耗在寄存器,内核栈 虚拟内存上,缩短真正的进程运行时间
那么,既然上下文切换的系统影响如此之大,如何查看上下文切换的情况呢?
常见的工具,可以使用vmstat这个工具,来查看系统的上下文切换情况
vmstat是一个常用的系统性能分析工具,分析系统的内存使用情况,分析CPU上下文切换和中断次数
下面就是一个vmstat的使用示例
vmstat 5
这就是基本的使用,代表着每五秒输出一次数据
其中
cs 是每秒上下文切换的次数
in 是每秒中断的次数
r 是就绪队列的长度,正在运行和等待CPU的进程数
b 则是不可中断睡眠状态的进程数
上下文切换次数cs是33次,中断数为25 就绪队列和不可中断进程数都是0
vmstat只给出了系统总体的上下文切换情况,对于单个进程状态的查看,可以使用之前说的pidstat
加上-w选项,查看每个进程上下文切换的情况
比如pidstat -w 5
查看常见进程上下文切换的情况
输出结果
其中cswch是每秒自愿上下文切换次数
nvcswch是每秒非自愿上下文切换次数
自愿的上下文切换,是因为获取不到所需的资源,导致的上下文切换,IO 内存等系统资源不足的时候,就会出现自愿上下文切换
非自愿上下文切换,是指的进程由于时间片到了时间等原因,被系统强行调度,发送的上下文切换
比如大量进程都在争抢CPU,就会发生非自愿的上下文切换
那么上下文切换的频率是多少比较合适呢?
这需要我们利用案例进行找到这个标准的
这就需要使用一定的unix工具来进行操作了
首先sysbench,一个多线程的基准测试工具,用于评估不同参数下的数据库负载情况,我们利用其来模拟异常上下文切换的问题
首先是利用vmstat来查看空闲系统的上下文切换次数
vmstat 1 1
cs上下文切换是35,in中断次数是19,r b都是0
然后利用sysbench模拟系统多线程调度的瓶颈
sysbench –threads=10 –max-time=300 threads run
然后利用vsmstat进行查看上下文切换情况
vsmstat 1
每一秒输出一组数据
cs列的上下文切换次数从之前的35变为了139万次,
r是8,说明就绪队列长度到了8,超过了系统CPU个数2,有大量的CPU竞争
us 和 sy两列加起来的CPU使用率上升到100%,系统CPU使用率,sy列高达84%
in列,中断次数达到了1万
上面是CPU的就绪队列过长,正在运行和等待CPU的进程数过多,导致了大量的上下文切换,上下文切换导致了系统CPU的占用率过高
然后查看是哪些进程导致的
使用pidstat来进行查看 CPU和进程上下文切换的情况
pidstat -w -u 1
-w说明输出进程切换指标 -u输出cpu使用指标
pidstat输出的结果,说明最高的是sysbench
CPU使用率高达100%,上下文除了自己还有pidstat kworker sshd
这个线程但是这几个加一起,也比139万小得多
这是源自于
sybench模拟的单位是线程,而pidstat获取的时候,只有进程数据
如果需要显示线程数据,则需要在pidstat上加上-t参数,输出线程指标
pidstat -wt 1
虽然sysbench进程的上下文切换次数看起来不多,但是子线程的上下文切换次数却有很多
所以罪魁祸首,还是sysbench的进程
然后我们查看对应的中断次数问题
是什么类型的中断,关于这个中断查询,我们需要从/proc/interrupts这个只读文件中读取,/proc实际上是Linux的一个虚拟文件系统,用于内核空间和用户空间之间的通信
我么看一下对应的中断信息
watch -d cat /proc/interrupts
主要的中断来源于
Resheduling,RES 重调度中断
这个中断类型表示,唤醒空闲的CPU进行新任务的运行,这种中断也被称为处理器间中断
这一个观察,我们就用了
pidstat和vmstat 最后直接看了log文件
你怎么上下文切换每秒次数多少才算合适呢?
这个数值取决于系统本身的CPU性能,一般每秒数百到1万都是正常,但是超过1万的时候
就可能性能问题了
最后
如果自愿上下文切换变多了,就说明进程都在等待资源,可能发生了IO等其他问题
如果非自愿上下文切换变多了,说明都在被强制调度,说明CPU是瓶颈
中断次数变多了,说明CPU被中断处理程序占用,需要查看 /proc/interrupts来分析具体的中断类型
我们还有别的分析和排查上下文切换问题的方式吗?
可以先使用uptime查看系统负载
然后mpstat结合pidstat进行判断CPU计算量大还是进程争抢过大,或者io过多导致的
stress和sysbench对不发现
stress是多进程的,导致进程上下文切换,us开销高
sysbench基于多线程的,是多线程,单一进程基于内核线程切换,导致sy的内核开销很高