現網有兩臺虛擬機主機95%的cpu處於idle狀態,內存使用率也不是特別高,而主機的load average達到了40多。html
先在主機上經過top、free、ps、iostat 等經常使用工具分析了下主機的CPU、內存、IO使用狀況,發現三者都不高。經過vmstat 1 查看的結果以下:linux
從vmstat的輸出結果來看,io項的block in 和block out 並不頻繁。而system項的每稱的中斷數(in)、每秒的上下文切換(cs)特別頻繁。這就形成load avaerage會特別高。大方向上的根因找到了,具體是哪一個進程如何頻繁的進行中斷和上下文件的切換呢?ios
這裏使用pidstat -w 1 (每秒刷新輸出上下文切換狀況),輸出見下圖:git
從上圖中能夠看到有cswch(自願的上下文切換)和nvcswch(非自願的上下文切換)及對應的命令, 出vsftpd佔用的文件交換比較多。能夠看到這裏顯示的cs 值和總值仍是有比較大的差距,因爲主機上啓動了不止一個vsftpd進程,並且pidstat 經過1秒刷新的時候並不會顯示全部,經過pidstat -w執行幾回收集全部發現全部的vsftpd進程佔用的cs值疊加和vmstat裏的比較相近了。github
將結果通知業務人員後,和業務人員的猜想也一致,因爲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上運行:測試
這樣作的原理是每當進程在切換到下一個cpu core上進會flush當前的cache數據,指定CPU時會減小這樣的操做,增長進程的處理速度。這個對老的程序調優時比較有效。spa
什麼是上下文件切換呢?引用老外的一句話: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之間的共享數據。
對於搶佔式操做系統而言, 大致有幾種:
什麼樣的操做會引發CS,這裏有一篇博文感受寫的很不錯,雖然其中的代碼部分並非理解 。其中有以下幾句話:
linux中一個進程的時間片到期,或是有更高優先級的進程搶佔時,是會發生CS的,但這些都是咱們應用開發者不可控的 ---前面一部分描述的很到位,後面一部分在系統層面和kernel 開發層面能夠調用nice 或 renice進行設置優先級以保證某些程序優先在CPU中的佔用時間,但也不能細化到CS層面。
站在開發者的角度,咱們的進程能夠主動地向內核申請進行CS 。操做方法爲:休眠當前進程/線程;喚醒其餘進程/線程 。
一、LMbench 是帶寬(讀取緩存文件、內存拷貝、讀寫內存、管道等)和反應時間(上下文切換、網路、進程建立等)的評測工具;
二、micro-benchmark contextswitch 能夠測試不一樣的CPU在最少多少ns能夠進行一次上下文件切換,再轉化爲秒,咱們能夠確認該處理器每能夠進行的上下文件切換數 ,該工具的使用能夠參看tsuna的blog。
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