linux中进程上下文频繁切换导致load average过高

一、问题现象

 

现网有两台虚拟机主机95%的cpu处于idle状态,内存使用率也不是特别高,而主机的load average达到了40多。

 

二、问题分析

 

先在主机上通过top、free、ps、iostat 等常用工具分析了下主机的CPU、内存、IO使用情况,发现三者都不高。通过vmstat 1 查看的结果如下:

 

 

从vmstat的输出结果来看,io项的block in 和block out 并不频繁。而system项的每称的中断数(in)、每秒的上下文切换(cs)特别频繁。这就造成load avaerage会特别高。大方向上的根因找到了,具体是哪个进程如何频繁的进行中断和上下文件的切换呢?

 

这里使用pidstat -w 1 (每秒刷新输出上下文切换情况),输出见下图:

 

 

从上图中可以看到有cswch(自愿的上下文切换)和nvcswch(非自愿的上下文切换)及对应的命令, 出vsftpd占用的文件交换比较多。可以看到这里显示的cs 值和总值还是有比较大的差距,由于主机上启动了不止一个vsftpd进程,而且pidstat 通过1秒刷新的时候并不会显示所有,通过pidstat -w执行几次收集所有发现所有的vsftpd进程占用的cs值叠加和vmstat里的比较相近了。

 

 

将结果通知业务人员后,和业务人员的猜测也一致,由于ftp使用的目录结构层次较深、文件数也比较多,业务在备份老的使用目录并重新创建单层目录后,观察一段后,发现load average降下来了,稳定在1以下。

 

当然这里只是处理方法的一种,现网中有些程序不好进行这样的修改的,又不让让进程在cpu之间频繁切换的,也有通过设置固定运行的CPU上进行调优的方法,如下两个进程运行在0-7号cpu上:

[root@www ~]# taskset -c -p 6389
pid 6389's current affinity list: 0-7
[root@www ~]# taskset -c -p 6580
pid 6580's current affinity list: 0-7
可以通过taskset让其固定在0-1号cpu上运行:

[root@www ~]# taskset -c 0,1 -p 6389
这样做的原理是每当进程在切换到下一个cpu core上进会flush当前的cache数据,指定CPU时会减少这样的操作,增加进程的处理速度。这个对老的程序调优时比较有效。

三、有关上下文切换

1、上下文切换的理解

什么是上下文件切换呢?引用老外的一句话:A context switch (also sometimes referred to as a process switch or a task switch) is the switching of the CPU (central processing unit) from one process or thread to another.更详细的说明可以参看linfo站点 或 维基百科 。

context switch过高会导致CPU像个搬运工,频繁在寄存器和运行队列之间奔波 ,更多的时间花在了线程切换,而不是真正工作的线程上。直接的消耗包括CPU寄存器需要保存和加载,系统调度器的代码需要执行。间接消耗在于多核cache之间的共享数据。

2、引起上下文切换的原因

对于抢占式操作系统而言, 大体有几种:

当前任务的时间片用完之后,系统CPU正常调度下一个任务;
当前任务碰到IO阻塞,调度线程将挂起此任务,继续下一个任务;
多个任务抢占锁资源,当前任务没有抢到,被调度器挂起,继续下一个任务;
用户代码挂起当前任务,让出CPU时间;
硬件中断;
什么样的操作会引起CS,这里有一篇博文感觉写的很不错,虽然其中的代码部分并不是理解 。其中有如下几句话:

linux中一个进程的时间片到期,或是有更高优先级的进程抢占时,是会发生CS的,但这些都是我们应用开发者不可控的 ---前面一部分描述的很到位,后面一部分在系统层面和kernel 开发层面可以调用nice 或 renice进行设置优先级以保证某些程序优先在CPU中的占用时间,但也不能细化到CS层面。

站在开发者的角度,我们的进程可以主动地向内核申请进行CS 。操作方法为:休眠当前进程/线程;唤醒其他进程/线程 。

3、上下文切换测试工具

1、LMbench 是带宽(读取缓存文件、内存拷贝、读写内存、管道等)和反应时间(上下文切换、网路、进程创建等)的评测工具;

2、micro-benchmark contextswitch 可以测试不同的CPU在最少多少ns可以进行一次上下文件切换,再转化为秒,我们可以确认该处理器每可以进行的上下文件切换数 ,该工具的使用可以参看tsuna的blog。

4、上下文切换的查看方法

sar -w ,这个只是能看出主机上总的上下文件切换的情况

# sar -w 1
proc/s
     Total number of tasks created per second.
cswch/s
     Total number of context switches per second.
同样,vmstat也可以查看总的上下文切换情况,不过vmstart输出的结果更多,便比通过对比发现问题:

# vmstat 3
procs -----------memory----------  ---swap-- -----io----  -system-- ----cpu----
 r  b   swpd   free   buff  cache    si   so    bi    bo   in    cs us sy id wa
 2  0   7292 249472  82340 2291972    0    0     0     0    0     0  7 13 79  0
 0  0   7292 251808  82344 2291968    0    0     0   184   24 20090  1  1 99  0
 0  0   7292 251876  82344 2291968    0    0     0    83   17 20157  1  0 99  0
 0  0   7292 251876  82344 2291968    0    0     0    73   12 20116  1  0 99  0
查看每个进程或线程的上下文件使用情况,可以使用pidstat命令或者通过查看proc 。

# pidstat -w   每个进程的context switching情况
# pidstat -wt  细分到每个threads
查看proc下的文件方法如下:
# pid=307
# grep ctxt /proc/$pid/status
voluntary_ctxt_switches:        41    #自愿的上下文切换
nonvoluntary_ctxt_switches:     16    #非自愿的上下文切换
cswch/s: 每秒任务主动(自愿的)切换上下文的次数,当某一任务处于阻塞等待时,将主动让出自己的CPU资源。

nvcswch/s: 每秒任务被动(不自愿的)切换上下文的次数,CPU分配给某一任务的时间片已经用完,因此将强迫该进程让出CPU的执行权。

上下文切换部分零零碎碎先到这里吧,只是想说明上下文切换还是比较重要的一个指标的。nagios check_mk默认有对上下文的监控,其使用的方法是通过两/proc/stat文件里取到ctxt行,并取两个时间段之间的差值来确认。

# cat /proc/stat|grep ctxt
ctxt 111751207

s

时间: 2024-08-02 17:29:26

linux中进程上下文频繁切换导致load average过高的相关文章

Linux中进程前后台切换相关命令

我们使用Linux时大多数是用shell命令行.一个命令窗口是无法直接执行多任务的.我们可以把某个任务先切到后台,再切别的任务到前台来操作.这个帖子整理一下这些常用的命令. 后台进程查看: jobs是用于后台进程查看的很方便的命令. jobs -l 可以显示出进程的pid. 注意一点:shell收到了SIGHUP信号后在退出前将SIGHUP转发给所有的作业(jobs).jobs由于收到SIGHUP而终止运行.(这取决于shell的) 将前台任务放到后台: 按下ctrl + z ,就将任务移到后台

Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】

转自:http://blog.csdn.net/laoliu_lcl/article/details/39972459 进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不断被提及,是最经常接触.看上去很懂但又说不清楚到底怎么回事.造成这种局面的原因,可能是原来接触到的操作系统课程的教学总停留在一种浅层次的理论层面上,没有深入去研究. 处理器总处于以下状态中的一种: 1.内核态,运行于进程上下文,内核代表进程运行于内核空间: 2.内核态,运行于中断上下文,内核代表硬件

zt:理解Linux中进程,线程等概念

http://www.linuxeden.com/doc/24482.html1 基本概念 1.1. 进程和线程可执行文件由指令和数据组成.进程就是在计算机上运行的可执行文件针对特定的输入数据的一个实例,同一个可执行程序文件如果操作不同的输入数据就是两个不同的进程.线 程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享其所附属的进程的所有的资源,包括打开的文件.页表(因此也就共享整个用户态 地址空间).信号标识及动态分配的内存等等.线程和进程的关系是:线程是属于进程的,线程

Linux中进程内存RSS与cgroup内存的RSS统计 - 差异

转载一篇关于进程内存计算和CGROUP内存计算差异的文章http://hustcat.github.io/memory-usage-in-process-and-cgroup/ 在Linux内核,对于进程的内存使用与Cgroup的内存使用统计有一些相同和不同的地方.进程的内存统计一般来说,业务进程使用的内存主要有以下几种情况:(1)用户空间的匿名映射页(Anonymous pages in User Mode address spaces),比如调用malloc分配的内存,以及使用MAP_ANO

Linux中进程管理命令的使用说明

kill 该命令用于终止一个程序.例如: [root@teacherroot]# kill 3793 Base: kill:(3793)- 没有那个进程 ps 该命令用于显示程序的状态.例子如下: [root@teacherroot]# ps PID TTY TIME CMD 3644 pts/0 00:00:00 bash 3852 pts/0 00:00:00 ps [root@teacher root]# ps –aux ︱grep "hong" Root 3793 0.0 0.

linux中帐户安全加固导致crontab -l无法输出

一.故障现象 数据库用户反馈在oracle用户下执行crontab -l 无法正常输出结果,而且有错误提示:Authentication token is no longer valid; new one required ,You (oracle) are not allowed to access to (crontab) because of pam configuration. .而其他用户执行正常. 二.故障处理与解决 由于提到了pam 配置,所以先是查看了/etc/pam.d/cro

linux下进程的最大线程数、进程最大数、进程打开的文件数【转】

转自:http://www.cnblogs.com/niocai/archive/2012/04/01/2428154.html ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_THREADS_MAX 这个限制可以在 /usr/include/bits/local_lim.h 中查看 对 linuxthreads 这个值一般是 1024,对于 nptl 则没有硬性的限制,仅仅受限于系统的资源 这个系统的资源主要就

Linux中线程和进程的区别

Linux中线程和进程的区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,它是系统进行资源分配和调度的一个独立单位.例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格.内存空间.磁盘空间.I/O设备等,然后该进程被放入到进程的就绪队列,进程调度程序选中它,为它分配CPU及其他相关资源,该进程就被运行起来. 线程是进程的一个实体,是CPU调度和分配的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器.一组寄存器和栈),但

Linux中查看进程及杀死进程命令

Linux中想杀死fcitx进程,然后再重启它. root@www.linuxidc.com:/home/zhangbin# ps -e | grep 'fcitx'  3405 ?        00:00:00 fcitx <defunct>  3415 ?        00:00:02 fcitx   不显示标题 root@www.linuxidc.com:/home/zhangbin# ps -h Warning: bad ps syntax, perhaps a bogus '-'