經過前面學習我麼你知道,過多的上下文切換,會把CPU時間消耗在寄存器、內核棧以及虛擬內存等數據的保存和回覆上,縮短進程
真正運行的時間,成了系統性能大幅降低的一個元兇ios
既然上下文切換對系統性能影響那麼大,你確定火燒眉毛想知道,道題怎麼查看上下文切換bash
[root@nfs ~]# vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 45668 1600548 0 341196 27 109 131 112 239 280 4 17 79 0 0 0 0 45668 1600556 0 341196 0 0 0 0 33 44 0 0 100 0 0 1 0 45668 1600556 0 341196 0 0 0 0 31 39 0 0 100 0 0 0 0 45668 1600556 0 341196 0 0 0 0 50 48 1 1 99 0 0 0 0 45668 1600556 0 341196 0 0 0 0 31 42 0 0 100 0 0 0 0 45668 1600556 0 341196 0 0 0 0 32 41 0 1 100 0 0 0 0 45668 1600556 0 341196 0 0 0 0 32 38 0 0 100 0 0 0 0 45668 1600556 0 341196 0 0 0 0 29 37 0 0 100 0 0 0 0 45668 1600556 0 341196 0 0 0 0 29 38 0 0 100 0 0
能夠看到這個例子中的上下文切換cs是280次,而系統中斷次數in則是239次,而就緒隊列長度r和不可中斷狀態是1進程數b都是0
只給出了系統總的上下文切換狀況,要想查看每一個進程的上下文切換的狀況了?服務器
$ pidstat -w -u 1 08:06:33 UID PID %usr %system %guest %wait %CPU CPU Command 08:06:34 0 10488 30.00 100.00 0.00 0.00 100.00 0 sysbench 08:06:34 0 26326 0.00 1.00 0.00 0.00 1.00 0 kworker/u4:2 UID PID cswch/s nvcswch/s Command 0 8 11.00 0.00 rcu_sched 0 16 1.00 0.00 ksoftirqd/1 0 471 1.00 0.00 hv_balloon 0 1230 1.00 0.00 iscsid 0 4089 1.00 0.00 kworker/1:5 0 4333 1.00 0.00 kworker/0:3 0 10499 1.00 224.00 pidstat 0 26326 236.00 0.00 kworker/u4:2 1000 26784 223.00 0.00 ssh
所謂自願上下文切換,是指進程沒法獲取所需自願,致使的上下文奇幻。好比好比說, I/O、內存等系統資源不足時,就會發生自願上下文切...是網絡
而非自願上下文奇幻,則是指進程因爲時間片已到等緣由,被系統強制調度,進而發生的上下文奇幻,好比大量進程都在爭搶 CPU 時,就容易發生非自願上下文切換多線程
機器配置:2 CPU,4GB 內存ssh
預先安裝 sysbenchcurl
cnetos 7.2工具
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash yum -y install sysbench
# 以 10 個線程運行 5 分鐘的基準測試,模擬多線程切換的問題 $ sysbench --threads=10 --max-time=300 threads run
# 每隔 1 秒輸出 1 組數據(須要 Ctrl+C 才結束)
[root@nfs ~]# vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 6 0 45412 1585156 0 351460 10 38 46 39 118 10 2 8 90 0 0 8 0 45412 1585156 0 351468 0 0 0 0 2023 2208584 17 83 0 0 0 7 0 45412 1585156 0 351468 0 0 0 0 2008 2183632 18 82 1 0 0 8 0 45412 1585156 0 351468 0 0 0 0 2013 2278429 17 83 0 0 0 8 0 45412 1585156 0 351468 0 0 0 0 2008 2251628 18 82 0 0 0 6 0 45412 1585156 0 351468 0 0 0 0 2014 2236468 19 81 0 0 0 7 0 45412 1585156 0 351468 0 0 0 0 2004 2255035 17 83 0 0 0 6 0 45412 1585156 0 351468 0 0 0 0 2020 2212782 18 82 1 0 0 7 0 45412 1585156 0 351468 0 0 0 0 2013 2194160 19 81 0 0 0
你應該能夠發現,cs列的上下文切換次數從以前的10驟然上升了220萬,同時,注意觀察其餘幾個指標post
r 列:就緒隊列的長度已經到了 8,遠遠超過了系統 CPU的個數2,因此確定會有大量的CPU競爭性能
us(user)和 sy(system)列:這兩列的 CPU使用率加起來上升到了 100%,其中系統CPU使用率,也就是sy列高達90%說明CPU主要被內核佔用了
in 列:中斷次數也上升到了 1 萬左右,說明中斷處理也是個潛在的問題
綜合這幾個指標,咱們能夠知道,系統的就緒隊列過長,也就是正在運行和等待的CPU進程數過多,致使大量的上下文切換,而上下文切換還又致使了系統CPU的佔用率升高
那麼究竟是是哪一個進程致使了這些問題了
[root@nfs ~]# pidstat -w -u 1 Linux 3.10.0-957.12.1.el7.x86_64 (nfs) 05/03/2019 _x86_64_ (2 CPU) 12:58:57 PM UID PID %usr %system %guest %wait %CPU CPU Command 12:58:59 PM 0 9183 31.07 162.14 0.00 0.00 193.20 0 sysbench 12:58:59 PM 0 9196 0.00 0.97 0.00 0.00 0.97 0 kworker/0:0 12:58:57 PM UID PID cswch/s nvcswch/s Command 12:58:59 PM 0 3 1.94 0.00 ksoftirqd/0 12:58:59 PM 0 9 7.77 0.00 rcu_sched 12:58:59 PM 0 103 1.94 0.00 kworker/1:2 12:58:59 PM 0 5823 10.68 0.00 vmtoolsd 12:58:59 PM 0 6969 0.97 0.00 sshd 12:58:59 PM 0 9066 0.97 0.00 kworker/u256:1 12:58:59 PM 0 9195 0.97 0.00 vmstat 12:58:59 PM 0 9196 1.94 0.00 kworker/0:0 12:58:59 PM 0 9198 0.97 0.00 pidstat ^C
從 pidstat 的輸出你能夠發現,CPU 使用率的升高果真是 sysbench 致使的,它的 CPU 使用率已經達到了 100%可是上下文切換則是來自其餘進程,包括非自願上下文切換頻率最高的pidstat
以及自願上下文切換頻率最高的內核線程kworker 和 sshd
不過,細心的你確定也發現了一個怪異的事兒:pidstat 出的上下文切換次數,加起來也就幾百,比 vmstat 的 220萬明顯小了太多。這是怎麼回事呢?難道是工具自己出了錯嗎?
經過運行 man pidstat ,你會發現,pidstat默認顯示進程的指標數據,加上 -t 參數後,纔會輸出線程的指標
咱們仍是在第三個終端裏, Ctrl+C 中止剛纔的 pidstat 命令,而後運行下面的命令,觀察中斷的變化狀況.
[root@nfs ~]# pidstat -wt 1 Linux 3.10.0-957.12.1.el7.x86_64 (nfs) 05/03/2019 _x86_64_ (2 CPU) 01:00:35 PM UID TGID TID cswch/s nvcswch/s Command 01:00:36 PM 0 3 - 0.93 0.00 ksoftirqd/0 01:00:36 PM 0 - 3 0.93 0.00 |__ksoftirqd/0 01:00:36 PM 0 9 - 17.76 0.00 rcu_sched 01:00:36 PM 0 - 9 17.76 0.00 |__rcu_sched 01:00:36 PM 0 14 - 3.74 0.00 ksoftirqd/1 01:00:36 PM 0 - 14 3.74 0.00 |__ksoftirqd/1 01:00:36 PM 0 103 - 1.87 0.00 kworker/1:2 01:00:36 PM 0 - 103 1.87 0.00 |__kworker/1:2 01:00:36 PM 0 5823 - 10.28 0.00 vmtoolsd 01:00:36 PM 0 - 5823 10.28 0.00 |__vmtoolsd 01:00:36 PM 0 - 6755 0.93 0.00 |__tuned 01:00:36 PM 0 - 6666 0.93 0.00 |__in:imjournal 01:00:36 PM 0 6969 - 0.93 0.00 sshd 01:00:36 PM 0 - 6969 0.93 0.00 |__sshd 01:00:36 PM 0 9066 - 0.93 0.00 kworker/u256:1 01:00:36 PM 0 - 9066 0.93 0.00 |__kworker/u256:1 01:00:36 PM 0 - 9184 37752.34 157714.02 |__sysbench 01:00:36 PM 0 - 9185 43673.83 153500.00 |__sysbench 01:00:36 PM 0 - 9186 32598.13 150383.18 |__sysbench 01:00:36 PM 0 - 9187 31631.78 179364.49 |__sysbench 01:00:36 PM 0 - 9188 43047.66 129503.74 |__sysbench 01:00:36 PM 0 - 9189 25115.89 170748.60 |__sysbench 01:00:36 PM 0 - 9190 40545.79 179413.08 |__sysbench 01:00:36 PM 0 - 9191 48101.87 157711.21 |__sysbench 01:00:36 PM 0 - 9192 31725.23 164217.76 |__sysbench 01:00:36 PM 0 - 9193 37538.32 159869.16 |__sysbench 01:00:36 PM 0 9195 - 0.93 0.00 vmstat 01:00:36 PM 0 - 9195 0.93 0.00 |__vmstat 01:00:36 PM 0 9196 - 1.87 0.00 kworker/0:0 01:00:36 PM 0 - 9196 1.87 0.00 |__kworker/0:0 01:00:36 PM 0 9200 - 0.93 0.93 pidstat 01:00:36 PM 0 - 9200 0.93 0.93 |__pidstat
如今你就能看到了,雖然 sysbench 進程(也就是主線程)的上下文切換次數看起來並很少,但它的子線程的上下文切換粗疏卻又不少,
看來,上下文切換醉魁禍首,仍是過多的線程
[root@nfs ~]# tail -15 /proc/interrupts IWI: 6600 5405 IRQ work interrupts RTR: 0 0 APIC ICR read retries RES: 22360 25295 Rescheduling interrupts CAL: 1158 647 Function call interrupts TLB: 23862 8639 TLB shootdowns TRM: 0 0 Thermal event interrupts THR: 0 0 Threshold APIC interrupts DFR: 0 0 Deferred Error APIC interrupts MCE: 0 0 Machine check exceptions MCP: 35 35 Machine check polls ERR: 0 MIS: 0 PIN: 0 0 Posted-interrupt notification event NPI: 0 0 Nested posted-interrupt event PIW: 0 0 Posted-interrupt wakeup event
觀察一段時間,你能夠發現,變化速度最快的是重調度中斷,這中斷相似表示,喚醒空閒狀態的CPU來調度新的任務運行,這是多處理器中,調度器用來分散任務到不一樣CPU的機制,一般也被稱爲處理間中斷
cswch過多說明資源IO問題,nvcswch過多說明調度爭搶cpu過多,中斷次數變多說明cpu被中斷程序調用
這個數值其實取決於系統自己的CPU性能,在我看來,若是系統上下文切換次數比較穩定,那麼從數百一萬之內,都有應該算是正常的,
但當上下文奇幻次數超過一萬次,或者切換次數出現數量級的增加時,就極可能已經出現性能問題
自願上下文切換變多了,說明進程都在等待自願,有可能發生了I/O等其餘問題;
非自願上下文切換變多了,說明進程都在被強制調動,也就是在爭搶CPU,說明CPU的確成了瓶頸
中斷次數變多了了,說明CPU被中斷處理程序佔用,還須要經過查看/proc/interrupts 文件來分析具體的中斷類型。
Step1: 首先經過uptime看下最近一段時間的負載怎麼樣,可以得出是徒然變高仍是變高已經有一段時間了,比較5min和15min系統負載的數據
Step2: 分析系統負載高的緣由有哪些?根據前面學習的,多是計算密集型任務致使,IO密集型任務致使,還有多是大量線程等待調度致使,還有多是幾種狀況的組合同時存在。這裏要怎麼分析能夠經過mpstat工具來區分,主要關注的幾個指標是%idle %iowait %wait
Step3: 若是經過上一步確認是大量線程等待調度致使,那麼能夠經過vmstat來查看系統總體的上下文切換狀況,主要關注cs/in/r/b 四個指標
Step4: 咱們已經知道了系統負載高的緣由,進一步經過pidstat 查看具體是那一個線程致使的詳細緣由
登陸到服務器,如今系統負載怎麼樣 。 高的話有三種狀況,首先是cpu使用率 ,其次是io使用率 ,以後就是二者都高 。
cpu 使用率高,可能確實是使用率高, 也的可能實際處理不高而是進程太多切換上下文頻繁 , 也多是進程內線程的上下文切換頻繁
io 使用率高 , 說明 io 請求比較大, 多是 文件io 、 網絡io 。
工具 :
系統負載 : uptime ( watch -d uptime)看三個階段平均負載
系統總體狀況 : mpstat (mpstat -p ALL 3) 查看 每一個cpu當前的總體情況,能夠重點看用戶態、內核態、以及io等待三個參數
系統總體的平均上下文切換狀況 : vmstat (vmstat 3) 能夠重點看 r (進行或等待進行的進程)、b (不可中斷進程/io進程) 、in (中斷次數) 、cs(上下文切換次數)
查看詳細的上下文切換狀況 : pidstat (pidstat -w(進程切換指標)/-u(cpu使用指標)/-wt(線程上下文切換指標)) 注意看是自願上下文切換、仍是被動上下文切換
io使用狀況 : iostat