平均负载及CPU上下文切换
平均負載
平均負載是指單位時間內,系統處于?可運行狀態?和?不可中斷狀態?的平均進程數。簡單理解,就是平均活躍進程數。
- 可運行狀態:進程正在或等待使用CPU
- 不可中斷狀態:進程正在等待硬件設備的I/O,是系統對進程和硬件設備的一種保護機制。
最理想的情況是,每個CPU上剛好運行著1個進程,也就是平均負載等于CPU的個數。假如平均負載是2,那么意味著:
- 單核CPU上,有一半的進程競爭不到CPU
- 雙核CPU上,所有的CPU剛好被完全占用
- 4核CPU上,意味著CPU有50%的空閑(idle)
注意,這里的核指邏輯核數,比如超線程的雙核CPU,相當于4核。
因此,當平均負載比CPU個數還大時,就出現了系統過載。
在生產環境中,一般推薦平均負載不要高于CPU數量的70%
區別CPU使用率
CPU使用率是單位時間內CPU繁忙情況的統計。而平均負載包括正在使用CPU、等待CPU、等待IO的進程。具體來說:
- CPU密集型進程,CPU使用率高,平均負載高
- I/O密集型進程,平均負載高,CPU使用率低
- 大量等待CPU的進程,平均負載高,CPU使用率也會比較高
案例分析
準備工具
linux系統,并安裝以下兩款工具:yum install stress sysstat
- stress: linux系統壓力測試工具
- sysstat:包含了常用的linux性能工具,這里用到它提供的兩個命令:
- mpstat: 多核CPU性能分析工具
- pidstat: 進程性能分析工具,可實時查看cpu, 內存,I/O以及上下文切換等指標
場景一:CPU密集型進程
以root身份登錄中斷,在終端1執行如下命令:
stress --cpu 2 --timeout 600 # 產生2個進程,壓測CPU 600秒, 具體命令參考 man stress說明終端2執行uptime查看平均負載的變化情況
# watch 監測 -d 表示高亮顯示變化的部分 watch -d uptimeEvery 2.0s: uptime Wed Dec 26 20:39:47 201820:39:47 up 54 days, 2:56, 4 users, load average: 0.93, 4.30, 3.23終端3查看CPU使用率變化:
mpstat -P ALL 2 5 # 每兩秒刷新下所有CPU的統計報告,一共刷新顯示顯示5次。如果不指定最后一個5,那么將一直刷新。 mpstat -P ALL 2 Linux 3.10.0-693.11.1.el7.x86_64 (iz2zeap40j01vg100ifsf4z) 12/26/2018 _x86_64_ (2 CPU)08:41:38 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 08:41:43 PM all 33.56 0.00 2.01 0.00 0.00 0.00 0.00 0.00 0.00 64.43 08:41:43 PM 0 17.37 0.00 1.27 0.00 0.00 0.00 0.00 0.00 0.00 81.36 08:41:43 PM 1 92.19 0.00 6.25 0.00 0.00 0.00 0.00 0.00 0.00 1.56# 其中一個CPU的使用率非常高, 但iowait為0,說明平均負載的升高是由CPU使用率高造成的。使用查看導致CPU升高的進程:
pidstat -u 2 1 # -u 報告CPU的使用率,2 每兩秒,1 報告一次 07:57:34 PM UID PID %usr %system %guest %CPU CPU Command 07:57:39 PM 0 9 0.00 0.20 0.00 0.20 1 rcu_sched 07:57:39 PM 0 479 100.00 0.00 0.00 100.00 0 stress 07:57:39 PM 0 1586 0.00 0.20 0.00 0.20 0 aliyun-service場景二:I/O 密集型進程
stress --io N --timeout 600 # 產生N個進程,模擬IO壓力場景三:大量進程的情況
stress --cpu 8 # 產生8個進程對CPU進行壓測由于系統只有兩個CPU,因此系統處于嚴重過載狀態:
uptime查看負載:1分鐘平均負載慢慢飆升到 8.97
20:36:39 up 62 days, 2:53, 5 users, load average: 8.97, 5.49, 2.86mpstat查看CPU統計數據,可以看到CPU 0 和 1 都滿了
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle Average: all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: 0 98.96 0.00 0.52 0.00 0.00 0.52 0.00 0.00 0.00 0.00 Average: 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00pidstat 查看系統任務統計(一個任務相當于一個進程)
Average: UID PID %usr %system %guest %CPU CPU Command Average: 0 1286 0.49 0.00 0.00 0.49 - java Average: 0 3270 23.15 0.00 0.00 23.15 - stress Average: 0 3271 25.62 0.00 0.00 25.62 - stress Average: 0 3272 23.65 0.00 0.00 23.65 - stress Average: 0 3273 27.09 0.00 0.00 27.09 - stress Average: 0 3274 25.12 0.00 0.00 25.12 - stress Average: 0 3275 21.67 0.00 0.00 21.67 - stress Average: 0 3276 25.62 0.00 0.00 25.62 - stress Average: 0 3277 23.15 0.00 0.00 23.15 - stress Average: 0 6453 0.49 0.00 0.00 0.49 - dockerd Average: 0 30783 0.00 0.49 0.00 0.49 - celeryCPU上下文切換
當活躍進程數大于CPU數量時,會出現競爭,CPU需要輪流執行這些進程,于是產生CPU上下文切換,這個切換是有開銷的,會導致負載升高。
查看CPU上下文切換
vmstat 用來查看虛擬內存,也可以查看一些CPU總體的上下文切換情況。
vmstat 5 1 # 5秒鐘輸出一組數據 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st1 0 0 124980 170900 1002128 0 0 22 14 1 1 2 1 97 0 00 0 0 124740 170900 1002144 0 0 0 1820 1074 1195 2 1 97 0 0有用參數
- cs: context switch 每秒鐘上下文切換次數
- in:interrupt 每秒鐘系統中斷次數
- r:running or runnable 就緒隊列的長度(運行中,等待運行的進程數)
- b:blocked 處于不可中斷的進程數(進程正在等待硬件設備的I/O)
使用pidstat -w查看每個進程的詳細情況:
pidstat -w 5Average: UID PID cswch/s nvcswch/s Command Average: 0 3 0.40 0.00 ksoftirqd/0 Average: 0 9 57.49 0.00 rcu_sched Average: 0 10 0.20 0.00 watchdog/0參數:
- cswch/s:voluntary context switches 自愿上下文切換,指進程無法獲取所需的自愿(I/O, 內存等系統資源不足時),發生自愿的上下文切換。
- nvcswch/s: non voluntary context switches 非自愿的上下文切換,進程的時間片到期,被系統強制發生的切換。當大量進程爭搶CPU時,就會發生非自愿的上下文切換
模擬測試
安裝sysbench,多線程基準測試工具:yum install sysbench sysstat
輸入如下命令模擬系統多線程調度的瓶頸:
sysbench --threads=10 --max-time=300 threads run # 運行10個線程,5分鐘新開一個終端,查看上下文切換情況:
vmstat 1 1 # 每秒刷新一次procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st9 0 0 296684 171112 1201540 0 0 21 14 2 2 2 1 97 0 06 0 0 296560 171112 1201540 0 0 0 0 3081 1947126 12 88 0 0 06 0 0 296436 171112 1201540 0 0 0 0 3192 2086130 14 86 1 0 0可以發現如下特點:
- r 就緒隊列,長度達到9,超過系統CPU個數(2個)
- in 終端次數達到3000次
- cs 上下文切換次數達到每秒200萬次
- us + sy 的cpu使用率加起來達到100%,其中幾乎都被sys占用,說明CPU主要被內核占用了
綜合以上數據,得出結論:系統的就緒隊列過長,導致了大量的上下文切換,大量上下文切換又導致了CPU的占用率升高。
下面我們通過pidstat命令來查看具體情況:
pidstat -wu 1 2 # -w 輸出切換指標 -u 輸出CPU使用率 1秒刷新一次,一共刷新2次08:58:30 PM UID PID %usr %system %guest %CPU CPU Command 08:58:31 PM 0 1286 1.00 0.00 0.00 1.00 1 java 08:58:31 PM 0 3871 1.00 1.00 0.00 2.00 1 AliYunDun 08:58:31 PM 999 7145 1.00 0.00 0.00 1.00 1 redis-server 08:58:31 PM 0 9626 1.00 0.00 0.00 1.00 1 celery 08:58:31 PM 0 9627 1.00 0.00 0.00 1.00 0 celery 08:58:31 PM 0 11201 31.00 100.00 0.00 100.00 1 sysbench # 100% CPU08:58:30 PM UID PID cswch/s nvcswch/s Command 08:58:31 PM 0 9 65.00 0.00 rcu_sched 08:58:31 PM 0 13 2.00 0.00 ksoftirqd/1 08:58:31 PM 0 266 3.00 0.00 kworker/0:1H 08:58:31 PM 0 271 4.00 0.00 jbd2/vda1-8 08:58:31 PM 0 1267 10.00 0.00 wrapper 08:58:31 PM 0 1439 12.00 0.00 PM2 # ...08:58:31 PM UID PID %usr %system %guest %CPU CPU Command 08:58:32 PM 0 11201 30.00 100.00 0.00 100.00 1 sysbench 08:58:32 PM 0 11213 0.00 1.00 0.00 1.00 1 pidstat08:58:31 PM UID PID cswch/s nvcswch/s Command 08:58:32 PM 0 9 58.00 0.00 rcu_sched 08:58:32 PM 0 13 1.00 0.00 ksoftirqd/1 08:58:32 PM 0 482 1.00 0.00 irqbalance 08:58:32 PM 0 1267 10.00 0.00 wrapper 08:58:32 PM 0 1439 12.00 0.00 PM2 # ...觀察輸出,發現sysbench確實導致了CPU使用率升高,但是上下文切換來自其他進程,并且數量加起來都不到3位數,那為什么vmstat中觀察到了200萬了,這是為什么?
這是因為線程是系統調度的基本單位,而且sysbench模擬的是線程調度。因此,只需加一個-t參數,就可以查看線程切換了:
pidstat -wut 1 309:09:18 PM UID TGID TID %usr %system %guest %CPU CPU Command 09:09:19 PM 0 1267 - 1.00 0.00 0.00 1.00 1 wrapper 09:09:19 PM 0 - 3818 1.00 0.00 0.00 1.00 0 |__AliYunDunUpdate 09:09:19 PM 0 - 3872 1.00 0.00 0.00 1.00 0 |__AliYunDun 09:09:19 PM 0 11290 - 34.00 100.00 0.00 100.00 1 sysbench 09:09:19 PM 0 - 11291 4.00 15.00 0.00 19.00 0 |__sysbench 09:09:19 PM 0 - 11292 3.00 16.00 0.00 19.00 1 |__sysbench 09:09:19 PM 0 - 11293 3.00 15.00 0.00 18.00 1 |__sysbench 09:09:19 PM 0 - 11294 3.00 14.00 0.00 17.00 0 |__sysbench 09:09:19 PM 0 - 11295 3.00 17.00 0.00 20.00 0 |__sysbench 09:09:19 PM 0 - 11296 4.00 19.00 0.00 23.00 0 |__sysbench 09:09:19 PM 0 - 11297 3.00 16.00 0.00 19.00 0 |__sysbench 09:09:19 PM 0 - 11298 4.00 16.00 0.00 20.00 0 |__sysbench 09:09:19 PM 0 - 11299 3.00 15.00 0.00 18.00 0 |__sysbench 09:09:19 PM 0 - 11300 3.00 15.00 0.00 18.00 0 |__sysbench 09:09:19 PM 0 11302 - 0.00 1.00 0.00 1.00 1 pidstat 09:09:19 PM 0 - 11302 0.00 1.00 0.00 1.00 1 |__pidstat09:09:18 PM UID TGID TID cswch/s nvcswch/s Command # ... 09:09:19 PM 0 9631 - 5.00 0.00 celery 09:09:19 PM 0 - 9631 5.00 0.00 |__celery 09:09:19 PM 0 - 9668 2.00 0.00 |__celery 09:09:19 PM 0 - 9669 2.00 0.00 |__celery 09:09:19 PM 0 9632 - 4.00 0.00 celery 09:09:19 PM 0 - 9632 4.00 0.00 |__celery 09:09:19 PM 0 - 9674 2.00 0.00 |__celery 09:09:19 PM 0 - 9675 2.00 0.00 |__celery 09:09:19 PM 0 11267 - 1.00 0.00 kworker/1:1 09:09:19 PM 0 - 11267 1.00 0.00 |__kworker/1:1 09:09:19 PM 0 - 11291 22986.00 175294.00 |__sysbench 09:09:19 PM 0 - 11292 28215.00 170894.00 |__sysbench 09:09:19 PM 0 - 11293 23272.00 138182.00 |__sysbench 09:09:19 PM 0 - 11294 34244.00 151715.00 |__sysbench 09:09:19 PM 0 - 11295 31714.00 167521.00 |__sysbench 09:09:19 PM 0 - 11296 20949.00 194500.00 |__sysbench 09:09:19 PM 0 - 11297 30983.00 185232.00 |__sysbench 09:09:19 PM 0 - 11298 28358.00 172171.00 |__sysbench 09:09:19 PM 0 - 11299 29662.00 159875.00 |__sysbench 09:09:19 PM 0 - 11300 27557.00 148900.00 |__sysbench 09:09:19 PM 0 11302 - 2.00 4.00 pidstat 09:09:19 PM 0 - 11302 2.00 4.00 |__pidstat # ...從上述輸出可以觀察到,sysbench的線程的大量切換。
另外,如果要查看中斷次數,可以讀取這個文件/proc/interrupts:
/proc 實際上是 Linux 的一個虛擬文件系統,用于內核空間與用戶空間之間的通信。/proc/interrupts 就是這種通信機制的一部分,提供了一個只讀的中斷使用情況。
watch -d cat /proc/interrupts # 高亮顯示中斷文件的變動部分Every 2.0s: cat /proc/interrupts Thu Jan 10 21:20:13 2019CPU0 CPU10: 20 0 IO-APIC-edge timer1: 10 0 IO-APIC-edge i80426: 3 0 IO-APIC-edge floppy8: 0 0 IO-APIC-edge rtc09: 0 0 IO-APIC-fasteoi acpi10: 0 0 IO-APIC-fasteoi virtio411: 35 0 IO-APIC-fasteoi uhci_hcd:usb112: 15 0 IO-APIC-edge i804214: 0 0 IO-APIC-edge ata_piix15: 5756484 0 IO-APIC-edge ata_piix24: 0 0 PCI-MSI-edge virtio2-config25: 2673089 5845758 PCI-MSI-edge virtio2-req.026: 1 0 PCI-MSI-edge virtio0-config27: 1868713 37408103 PCI-MSI-edge virtio0-input.028: 349576 44643775 PCI-MSI-edge virtio0-output.029: 0 0 PCI-MSI-edge virtio3-config30: 326128 0 PCI-MSI-edge virtio3-req.031: 0 0 PCI-MSI-edge virtio1-config32: 22 0 PCI-MSI-edge virtio1-virtqueues NMI: 0 0 Non-maskable interrupts LOC: 2924265642 2872116981 Local timer interrupts SPU: 0 0 Spurious interrupts PMI: 0 0 Performance monitoring interrupts IWI: 60559294 62135237 IRQ work interrupts RTR: 0 0 APIC ICR read retries RES: 296793417 297917656 Rescheduling interrupts CAL: 18746994 956271 Function call interrupts TLB: 5927981 5878741 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從中可以觀察到,以下兩個參數在不斷變化
- Local timer interrupts
- Rescheduling interrupts 重新調度中斷(RES),表示喚醒空閑狀態的CPU來調度新的任務運行,這是多處理器系統中,調度器用來分散任務到不同CPU的機制
結論
每秒上下文切換次數的大小,取決于CPU性能,一般來說,切換穩定,數值從百到萬以內,都算正常:
- cswch/s 切換多,說明進程在等待資源,可能發生了I/O等其他問題
- nvcswch/sq 切換多,說明進程被強制調度,也就是爭搶CPU,說明CPU有瓶頸
- 中斷次數多了,說明CPU被中斷程序占用,具體可以分析 /proc/interrupts文件
總結
以上是生活随笔為你收集整理的平均负载及CPU上下文切换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 汉字转拼音pinyin4
- 下一篇: ORACLE EBS财务科目FLEX F