[转帖]如何分析上下文切换问题

如何,分析,上下文,切换,问题 · 浏览次数 : 0

小编点评

**上下文切换变多** 由于系统间机制,多个工具、多个方面指标对比观测上下文切换变多。自愿上下文切换变多,说明进程都在等待资源,有可能发生I/O等其他问题。非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢cpu。中断次数变多了,说明cpu被中断吃你程序占用,需要通过/proc/interrups文件来分析具体的中断类型。 **分析方法** 1. **/proc/interrupts文件**观察中断次数变化,分析不同工具之间的上下文切换变多。 2. **自愿上下文切换变多**分析进程等待资源和争抢cpu之间的情况。 3. **非自愿上下文切换变多**分析进程被强制调度的情况。 4. **中断次数变多**分析cpu被中断吃你程序占用的情况。 **总结** 上下文切换变多,说明进程都在等待资源,有可能发生I/O等其他问题。自愿上下文切换变多,说明进程都在被强制调度,也就是在争抢cpu。中断次数变多,说明cpu被中断吃你程序占用,需要通过/proc/interrups文件来分析具体的中断类型。

正文

https://www.jianshu.com/p/40188dff99e9

 

vmstat

vmstat:是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析cpu上下文切换和中断次数

[wanchao@localhost ~]$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 3  0      0 1168240    932 531912    0    0     7  1034   65  667  2  2 96  1  0
 0  0      0 1168240    932 531912    0    0     0    37   36   65  0  0 100  0  0
 0  0      0 1168240    932 531912    0    0     0     5   41   74  0  0 100  0  0
  • cs(context switch)是每秒上下文切换的次数
  • in(interrupt)则是每秒中断的次数
  • r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待cpu的进程数
  • b(Blocked)则是处于不可中断睡眠状态的进程数

pidstat

vmstat只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,就需要使用我们前面提到过的pidstat了。给它加上 -w选项,你就可以查看每个进程上下文切换的情况

[wanchao@localhost ~]$ pidstat -w 5    #每隔5秒输出一组数据
Linux 3.10.0-327.el7.x86_64 (localhost.localdomain)     02/08/23    _x86_64_    (1 CPU)

18:53:59      UID       PID   cswch/s nvcswch/s  Command
18:54:04        0         3      0.37      0.00  ksoftirqd/0
18:54:04        0       137      1.69      0.00  rcu_sched
18:54:04        0       138      1.12      0.00  rcuos/0
18:54:04        0       266      0.19      0.00  watchdog/0
18:54:04        0       825      0.19      0.00  auditd
18:54:04        0       847      9.93      0.00  vmtoolsd
18:54:04        0       884      0.94      0.00  rngd
18:54:04        0       897      0.19      0.00  crond
18:54:04        0     62042      0.94      0.00  kworker/u256:2
18:54:04        0     62864      2.06      0.19  kworker/0:0
18:54:04        0     62884      0.75      0.00  kworker/0:2H
18:54:04     1000     62885      0.19      0.00  pidstat
  • cswch(voluntary context switches):表示每秒自愿上下文切换的次数,指进程无法获取所需资源,导致的上下文切换。如:I/O、内存等系统资源不足时,就会发生自愿上下文切换。
  • nvcswch(non voluntary context switches):表示每秒非自愿上下文切换,则是进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。如:大量进程都在争抢cpu时,就容易发生非自愿上下文切换

案例分析

上面的vmstat执行结果便是空闲系统的上下文切换次数,cs是在70左右,in是40左右

1、使用sysbench模拟上下文切换过多的问题,以十个线程运行5分钟的基准测试,模拟多线程切换的问题

[wanchao@localhost ~]$ sysbench --threads=10 --max-time=300 threads run
WARNING: --max-time is deprecated, use --time instead
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 10
Initializing random number generator from current time
Initializing worker threads...
Threads started!

2、 使用vmstat,观察上下文切换情况:

[root@localhost ~]# vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 9  0      0 1158132    932 532396    0    0     7   985   64  449  2  2 96  1  0
 6  0      0 1158008    932 532396    0    0     0     0  158 2345591 11 89  0  0  0
 8  0      0 1156524    932 532468    0    0     0     0  113 1525236 11 89  0  0  0
 9  0      0 1156508    932 532468    0    0     0     0  147 2359798 14 86  0  0  0

1、 cs列:上下文切换次数从70骤然上升到234万
2、 r列:就绪队列的长度已经到了9,远远超过了系统的cpu个数1,所有就会有大量的cpu竞争
3、 us(user)和sy (system)列:这两列的cpu使用率加起来上升到了100%,其中系统使用率也就是sy列高达89%,说明cpu主要被内核占用了
4、 in列:中断次数300左右,不是很高
综合这几个指标,我们可以知道,系统的就绪队列过长,也就是正在运行和等待cpu的进程数过多,导致了大量的上下文切换,而上下文切换又导致了系统的cpu占用率升高。

3、 继续分析,使用pidstat看一下cpu和进程的上下文切换情况:

#-w参数表示输出进程切换指标,而-u参数则表示输出cpu使用指标
[root@localhost ~]# pidstat -w -u 1
19:40:25      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
19:40:26     1000     63139   14.85   91.09    0.00    0.00  105.94     0  sysbench
19:40:26        0     63151    0.00    1.98    0.00    0.00    1.98     0  pidstat

19:40:25      UID       PID   cswch/s nvcswch/s  Command
19:40:26        0       137      1.98      0.00  rcu_sched
19:40:26        0       138      1.98      0.00  rcuos/0
19:40:26        0       847      9.90      0.00  vmtoolsd
19:40:26        0       884      0.99      0.00  rngd
19:40:26        0     62042      0.99      0.00  kworker/u256:2
19:40:26     1000     62972      2.97      0.00  sshd
19:40:26        0     63105    205.94      0.00  kworker/0:0
19:40:26        0     63151      0.99    204.95  pidstat

从pidstat的输出可以发现,使用率的升高是sysbench导致的,它的cpu使用率已经达到100%。但上下文切换则是来自其他进程,包括非自愿上下文切换频率最高的pidstat,以及自愿上下文切换频率最高的内核线程kworker。

4、上面的pidstat -w是默认显示的进程指标数据,而sysbench模拟的是线程调度问题,所以上面显示cswch和nvcswch才仅仅有几百,和vmstat的几百万次相差甚远。pidstat加上-t参数,就可以输出线程指标:

#
[wanchao@localhost ~]$  pidstat -wt -u 5
Linux 3.10.0-327.el7.x86_64 (localhost.localdomain)     02/08/23    _x86_64_    (1 CPU)
21:30:31      UID      TGID       TID    %usr %system  %guest   %wait    %CPU   CPU  Command
21:30:37     1000     63306         -    6.15   83.73    0.00    0.00   89.87     0  sysbench
21:30:37     1000         -     63307    1.08    8.32    0.00    0.00    9.40     0  |__sysbench
21:30:37     1000         -     63308    0.54    8.68    0.00    0.00    9.22     0  |__sysbench
21:30:37     1000         -     63309    0.54    8.14    0.00    0.00    8.68     0  |__sysbench
21:30:37     1000         -     63310    0.54    8.32    0.00    0.00    8.86     0  |__sysbench
21:30:37     1000         -     63311    0.36    8.68    0.00    0.00    9.04     0  |__sysbench
21:30:37     1000         -     63312    1.08    8.14    0.00    0.00    9.22     0  |__sysbench
21:30:37     1000         -     63313    0.54    8.68    0.00    0.00    9.22     0  |__sysbench
21:30:37     1000         -     63314    0.36    8.32    0.00    0.00    8.68     0  |__sysbench
21:30:37     1000         -     63315    0.54    8.14    0.00    0.00    8.68     0  |__sysbench
21:30:37     1000         -     63316    0.54    8.50    0.00    0.00    9.04     0  |__sysbench
21:30:37        0     63320         -    0.18    0.54    0.00    0.00    0.72     0  pidstat
21:30:37        0         -     63320    0.18    0.54    0.00    0.00    0.72     0  |__pidstat
21:30:31      UID      TGID       TID   cswch/s nvcswch/s  Command
21:30:37     1000         -     62930      0.18      0.00  |__sshd
21:30:37        0     63195         -      1.99      0.00  kworker/0:0
21:30:37        0         -     63195      1.99      0.00  |__kworker/0:0
21:30:37     1000     63306     63307   9937.43  82584.81  (sysbench)__sysbench
21:30:37     1000         -     63308  11930.02  77856.96  |__sysbench
21:30:37     1000         -     63309  12277.03  78040.51  |__sysbench
21:30:37     1000         -     63310  11256.60  79153.16  |__sysbench
21:30:37     1000         -     63311   9369.62  85189.69  |__sysbench
21:30:37     1000         -     63312   8365.28  85014.65  |__sysbench
21:30:37     1000         -     63313  10202.53  80580.11  |__sysbench
21:30:37     1000         -     63314  11838.70  78823.15  |__sysbench
21:30:37     1000         -     63315  13387.16  75047.38  |__sysbench
21:30:37     1000         -     63316  10794.03  82640.14  |__sysbench
21:30:37        0     63317         -      0.18      0.00  vmstat
21:30:37        0         -     63317      0.18      0.00  |__vmstat
21:30:37        0     63320         -      0.18      0.54  pidstat
21:30:37        0         -     63320      0.18      0.54  |__pidstat

这里我们就可以看到,上下文切换的罪魁祸首就是sysbench线程。

5、 前面虽然我们看到的中断次数不多,但是仍然是有增加,这里提供一个分析中断次数上升的方法,就是从/proc/interrupts这个只读文件中读取。/proc实际上是linux的一个虚拟文件系统,用于内核空间与用户空间之间的通信。/proc/interrupts就是这种通信机制的一部分,提供了一个只读的中断使用情况。

 -d 参数表示高亮显示变化区域
[wanchao@localhost ~]$ watch -d cat /proc/interrupts
          CPU0       
 19:      73600   IO-APIC-fasteoi   eno16777736

这里变化最快的是是网卡,因为没有中断次数过多的异常,且由于我的环境只有一个cpu,不是多处理其系统(调度器用来分散任务到不同cpu的机制),不然就可以模拟出次此中断原因,通常也被称为处理器间中断(Inter-Processor Interrupts,IPI),这里只是提供一个分析思路。

通过这个案例,发现了多工具、多方面指标对比观测的好处,那么每秒上下文切换多少次才算正常呢?这个数值其实取决于系统本身的cpu性能。如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的。但当上下文切换次数超过一万次,户或者切换次数出现数量级增长时,就可能出现性能问题。

补充:

  • 自愿上下文切换变多,说明进程都在等待资源,有可能发生I/O等其他问题。
  • 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢cpu。
  • 中断次数变多了,说明cpu被中断吃你程序占用,需要通过/proc/interrups文件来分析具体的中断类型。

与[转帖]如何分析上下文切换问题相似的内容:

[转帖]如何分析上下文切换问题

https://www.jianshu.com/p/40188dff99e9 vmstat vmstat:是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析cpu上下文切换和中断次数 [wanchao@localhost ~]$ vmstat 5 procs memory s

[转帖]如何分析上下文切换问题

https://www.jianshu.com/p/40188dff99e9 vmstat vmstat:是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析cpu上下文切换和中断次数 [wanchao@localhost ~]$ vmstat 5 procs memory s

[转帖]Redis如何绑定CPU

文章系转载,便于分类和归纳,源文地址:https://www.yisu.com/zixun/672271.html 绑定 CPU Redis 6.0 开始支持绑定 CPU,可以有效减少线程上下文切换。 CPU 亲和性(CPU Affinity)是一种调度属性,它将一个进程或线程,「绑定」到一个或一组

[转帖]Redis如何绑定CPU

文章系转载,便于分类和归纳,源文地址:https://www.yisu.com/zixun/672271.html 绑定 CPU Redis 6.0 开始支持绑定 CPU,可以有效减少线程上下文切换。 CPU 亲和性(CPU Affinity)是一种调度属性,它将一个进程或线程,「绑定」到一个或一组

[转帖]tcpdump/wireshark 抓包及分析(2019)

http://arthurchiao.art/blog/tcpdump-practice-zh/ 本文将展示如何使用 tcpdump 抓包,以及如何用 tcpdump 和 wireshark 分析网络流量。 文中的例子比较简单,适合作为入门参考。 1 基础环境准备 为方便大家跟着上手练习,本文将搭建

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]如何判断oracle内存是否够用

https://www.modb.pro/db/431194 给数据库分配的内存,在topas当中看,是属于计算内存,从内存栈分类上来说是共享内存。如果给数据库分配XX GB内存,那么数据库使用的内存不含超过这个限制。但至于这些内存够不够用,就要看业务系统是否能够接受当前的响应时间等性能指标,能接受

[转帖]删除分区如何不让全局索引失效?

记得上次ACOUG年会(《ACOUG年会感想》),请教杨长老问题的时候,谈到分区,如果执行分区删除的操作,就会导致全局索引失效,除了使用12c以上版本能避免这个问题外,指出另外一种解决的方式,表面看很巧妙,实则是对分区原理的深入理解。 我们先从实验,了解这个问题,首先创建分区表,他存在4个分区,每个