当前位置: 首页 > 科技观察

LinuxCPU上下文切换故障排除_1

时间:2023-03-13 23:10:24 科技观察

在我的上一篇文章:《??探讨 Linux CPU 的上下文切换??》中,我谈到了CPU上下文切换是如何工作的。快速回顾一下,CPU上下文切换是保持Linux系统正常运行的核心功能。可分为进程上下文切换、线程上下文切换和中断上下文切换。在本文中,我将进一步讨论如何分析CPU上下文切换问题。考察CPU上下文切换我们知道,过多的上下文切换会消耗CPU时间保存和恢复寄存器、程序计数器、内核堆栈和虚拟内存等数据,导致系统性能显着下降。既然上下文切换对系统性能的影响如此之大,那么我们如何检查呢?那么,您可以使用vmstat工具来查询系统的上下文切换。vmstatvmstat是一个常用的系统性能分析工具。主要用来分析内存使用情况,也常用于分析CPU上下文切换次数和中断次数。例如vmstat5(5秒输出间隔):我们看一下输出:cs(contextswitch):每秒上下文切换的次数。in(interrupt):每秒的中断次数。r(running|runnable):就绪队列的长度,即正在运行并等待CPU的进程数。b(blocked):处于不可中断睡眠状态的进程数。在上面的例子中,我们可以看到上下文切换次数为33次,系统中断次数为25次,就绪队列长度,未中断状态进程数都为0。pidstatvmstat工具只是给出了信息关于系统的整体上下文切换。要查看每个进程的详细信息,您需要使用pidstat。添加-w选项,您可以看到每个进程的上下文切换:示例:#Outputintervalis5$pidstat-w5Linux4.15.0(ubuntu)09/23/18_x86_64_(2CPU)08:18:26UIDPIDcswch/snvcswch/sCommand08:18:31010.200.00systemd08:18:31085.400.00rcu_sched...结果中有两列需要我们注意:cswch和nvcswch。其中,cswch表示每秒自愿上下文切换次数,nvcswch表示每秒非自愿上下文切换次数。自愿上下文切换:指进程无法获取所需资源而引起的上下文切换。例如,当I/O和内存等系统资源不足时,会发生自愿上下文切换。Involuntarycontextswitch:指进程因为时间片过期而被系统强制重新调度时发生的上下文切换。例如,当大量进程竞争CPU时,很容易发生非自愿的上下文切换。您必须牢记这两个概念,因为它们意味着不同的性能问题。案例研究现在您知道如何查看这些指标,另一个问题出现了,上下文切换的频率是多少?让我们看一个例子。我们将使用sysbench(https://github.com/akopytov/sysbenc),这是一种多线程基准测试工具,可通过生成负载来模拟过多的上下文切换。假定您已经在Linux系统上安装了sysbench和sysstat。在我们模拟负载之前,我们先在终端运行vmstat:这里我们可以看到当前上下文切换次数cs为35,中断次数为19,r和b都是0.由于我目前没有其他任务在运行,因此它们是空闲系统中的上下文切换次数。现在让我们运行sysbench来模拟多线程调度系统的瓶颈:$sysbench--threads=10--max-time=300threadsrun现在,你应该看到vmstat输出与上面不同结果:你应该看到线程数量突然增加cs列的上下文切换次数从之前的35次增加到139万次。同时注意其他几个指标:r:就绪队列长度达到8ussy:us和sy合计CPU占用率100%,系统CPU占用率84%,说明CPU主要被内核占用。in:中断的数量也上升到10000,说明中断处理也是一个潜在的问题。结合这些指标,我们可以知道系统的就绪队列过长,即等待CPU的进程运行过多,导致大量的上下文切换,大量的上下文切换导致增加在系统的CPU使用率。那么是什么过程导致了这些问题呢?我们继续分析,在第三个终端使用pidstat查看CPU和进程上下文切换:#1meansoutputintervalis1second#-w:outputprocessswitchingindex,#-u:outputCPUusageindex$pidstat-w-u108:06:33UIDPID%usr%system%guest%wait%CPUCPUCommand08:06:3401048830.00100.000.000.00100.000sysbench08:06:340263260.001.000.000.001.000kworker/u4:208:06:33UIDPIDcswch/snvcswch/sCommand08:06:340811.000.00rcu_sched08:06:340161.000.00ksoftirqd/108:06:3404711.000.00hv_balloon08:06:34012301.000.00iscsid08:06:34040891.000.00kworker/1:508:06:34043331.000.00kworker/0:308:06:340104991.00224.00pidstat08:06:34026326236.000.00kworker/u4:208:06:34100026784223.000.00从pidstat的输出,sshd可以发现CPU占用率上升确实是sysbench引起的,其CPU占用率已经达到100%。但是上下文切换来自其他进程,包括具有最多非自愿上下文切换的pidstat,以及具有最多自愿上下文切换的内核线程kworker和sshd。注意:默认情况下,pidstat只显示进程的上下文切换,如果要查看实际线程的上下文切换,请添加-t选项。中断要找出中断数量也很高的原因,您可以查看/proc/interrupts文件。这个文件提供了一个只读的中断用法。#-d:Highlightthechangearea$watch-dcat/proc/interruptsCPU0CPU1...RES:24504315279697Reschedulinginterrupts...观察一段时间后可以发现变化最快的是重调度中断(RES,RESchedulinginterrupt)。这种中断类型表示一个空闲的CPU被唤醒来安排一个新的任务运行。所以这里的中断增加是因为任务调度问题太多了,这和前面分析上下文切换次数是一致的。现在回到最初的问题,每秒多少次上下文切换才算正常?这个值其实取决于系统本身的CPU性能。在我看来,如果系统的上下文切换次数比较稳定的话,几百到一万应该是正常的。但是,当上下文切换次数超过10000次,或者上下文切换次数快速增加时,很可能会出现性能问题。结论至此,您应该可以根据上下文切换的类型进行一些具体的分析。主动上下文切换较多,说明进程正在等待资源,可能会出现I/O饱和等其他问题。有很多不自觉的上下文切换,说明进程在被强制调度,也就是都在争CPU,说明CPU确实造成了瓶颈。如果中断次数增加,说明CPU被中断处理程序占用了。需要查看/proc/interrupts文件来分析具体的中断类型。