平均负载及CPU上下文切换
平均負(fù)載
平均負(fù)載是指單位時(shí)間內(nèi),系統(tǒng)處于?可運(yùn)行狀態(tài)?和?不可中斷狀態(tài)?的平均進(jìn)程數(shù)。簡(jiǎn)單理解,就是平均活躍進(jìn)程數(shù)。
- 可運(yùn)行狀態(tài):進(jìn)程正在或等待使用CPU
- 不可中斷狀態(tài):進(jìn)程正在等待硬件設(shè)備的I/O,是系統(tǒng)對(duì)進(jìn)程和硬件設(shè)備的一種保護(hù)機(jī)制。
最理想的情況是,每個(gè)CPU上剛好運(yùn)行著1個(gè)進(jìn)程,也就是平均負(fù)載等于CPU的個(gè)數(shù)。假如平均負(fù)載是2,那么意味著:
- 單核CPU上,有一半的進(jìn)程競(jìng)爭(zhēng)不到CPU
- 雙核CPU上,所有的CPU剛好被完全占用
- 4核CPU上,意味著CPU有50%的空閑(idle)
注意,這里的核指邏輯核數(shù),比如超線程的雙核CPU,相當(dāng)于4核。
因此,當(dāng)平均負(fù)載比CPU個(gè)數(shù)還大時(shí),就出現(xiàn)了系統(tǒng)過載。
在生產(chǎn)環(huán)境中,一般推薦平均負(fù)載不要高于CPU數(shù)量的70%
區(qū)別CPU使用率
CPU使用率是單位時(shí)間內(nèi)CPU繁忙情況的統(tǒng)計(jì)。而平均負(fù)載包括正在使用CPU、等待CPU、等待IO的進(jìn)程。具體來說:
- CPU密集型進(jìn)程,CPU使用率高,平均負(fù)載高
- I/O密集型進(jìn)程,平均負(fù)載高,CPU使用率低
- 大量等待CPU的進(jìn)程,平均負(fù)載高,CPU使用率也會(huì)比較高
案例分析
準(zhǔn)備工具
linux系統(tǒng),并安裝以下兩款工具:yum install stress sysstat
- stress: linux系統(tǒng)壓力測(cè)試工具
- sysstat:包含了常用的linux性能工具,這里用到它提供的兩個(gè)命令:
- mpstat: 多核CPU性能分析工具
- pidstat: 進(jìn)程性能分析工具,可實(shí)時(shí)查看cpu, 內(nèi)存,I/O以及上下文切換等指標(biāo)
場(chǎng)景一:CPU密集型進(jìn)程
以root身份登錄中斷,在終端1執(zhí)行如下命令:
stress --cpu 2 --timeout 600 # 產(chǎn)生2個(gè)進(jìn)程,壓測(cè)CPU 600秒, 具體命令參考 man stress說明終端2執(zhí)行uptime查看平均負(fù)載的變化情況
# watch 監(jiān)測(cè) -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 # 每?jī)擅胨⑿孪滤蠧PU的統(tǒng)計(jì)報(bào)告,一共刷新顯示顯示5次。如果不指定最后一個(gè)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# 其中一個(gè)CPU的使用率非常高, 但iowait為0,說明平均負(fù)載的升高是由CPU使用率高造成的。使用查看導(dǎo)致CPU升高的進(jìn)程:
pidstat -u 2 1 # -u 報(bào)告CPU的使用率,2 每?jī)擅?#xff0c;1 報(bào)告一次 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場(chǎng)景二:I/O 密集型進(jìn)程
stress --io N --timeout 600 # 產(chǎn)生N個(gè)進(jìn)程,模擬IO壓力場(chǎng)景三:大量進(jìn)程的情況
stress --cpu 8 # 產(chǎn)生8個(gè)進(jìn)程對(duì)CPU進(jìn)行壓測(cè)由于系統(tǒng)只有兩個(gè)CPU,因此系統(tǒng)處于嚴(yán)重過載狀態(tài):
uptime查看負(fù)載:1分鐘平均負(fù)載慢慢飆升到 8.97
20:36:39 up 62 days, 2:53, 5 users, load average: 8.97, 5.49, 2.86mpstat查看CPU統(tǒng)計(jì)數(shù)據(jù),可以看到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 查看系統(tǒng)任務(wù)統(tǒng)計(jì)(一個(gè)任務(wù)相當(dāng)于一個(gè)進(jìn)程)
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上下文切換
當(dāng)活躍進(jìn)程數(shù)大于CPU數(shù)量時(shí),會(huì)出現(xiàn)競(jìng)爭(zhēng),CPU需要輪流執(zhí)行這些進(jìn)程,于是產(chǎn)生CPU上下文切換,這個(gè)切換是有開銷的,會(huì)導(dǎo)致負(fù)載升高。
查看CPU上下文切換
vmstat 用來查看虛擬內(nèi)存,也可以查看一些CPU總體的上下文切換情況。
vmstat 5 1 # 5秒鐘輸出一組數(shù)據(jù) 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有用參數(shù)
- cs: context switch 每秒鐘上下文切換次數(shù)
- in:interrupt 每秒鐘系統(tǒng)中斷次數(shù)
- r:running or runnable 就緒隊(duì)列的長(zhǎng)度(運(yùn)行中,等待運(yùn)行的進(jìn)程數(shù))
- b:blocked 處于不可中斷的進(jìn)程數(shù)(進(jìn)程正在等待硬件設(shè)備的I/O)
使用pidstat -w查看每個(gè)進(jìn)程的詳細(xì)情況:
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參數(shù):
- cswch/s:voluntary context switches 自愿上下文切換,指進(jìn)程無法獲取所需的自愿(I/O, 內(nèi)存等系統(tǒng)資源不足時(shí)),發(fā)生自愿的上下文切換。
- nvcswch/s: non voluntary context switches 非自愿的上下文切換,進(jìn)程的時(shí)間片到期,被系統(tǒng)強(qiáng)制發(fā)生的切換。當(dāng)大量進(jìn)程爭(zhēng)搶CPU時(shí),就會(huì)發(fā)生非自愿的上下文切換
模擬測(cè)試
安裝sysbench,多線程基準(zhǔn)測(cè)試工具:yum install sysbench sysstat
輸入如下命令模擬系統(tǒng)多線程調(diào)度的瓶頸:
sysbench --threads=10 --max-time=300 threads run # 運(yùn)行10個(gè)線程,5分鐘新開一個(gè)終端,查看上下文切換情況:
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可以發(fā)現(xiàn)如下特點(diǎn):
- r 就緒隊(duì)列,長(zhǎng)度達(dá)到9,超過系統(tǒng)CPU個(gè)數(shù)(2個(gè))
- in 終端次數(shù)達(dá)到3000次
- cs 上下文切換次數(shù)達(dá)到每秒200萬次
- us + sy 的cpu使用率加起來達(dá)到100%,其中幾乎都被sys占用,說明CPU主要被內(nèi)核占用了
綜合以上數(shù)據(jù),得出結(jié)論:系統(tǒng)的就緒隊(duì)列過長(zhǎng),導(dǎo)致了大量的上下文切換,大量上下文切換又導(dǎo)致了CPU的占用率升高。
下面我們通過pidstat命令來查看具體情況:
pidstat -wu 1 2 # -w 輸出切換指標(biāo) -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 # ...觀察輸出,發(fā)現(xiàn)sysbench確實(shí)導(dǎo)致了CPU使用率升高,但是上下文切換來自其他進(jìn)程,并且數(shù)量加起來都不到3位數(shù),那為什么vmstat中觀察到了200萬了,這是為什么?
這是因?yàn)榫€程是系統(tǒng)調(diào)度的基本單位,而且sysbench模擬的是線程調(diào)度。因此,只需加一個(gè)-t參數(shù),就可以查看線程切換了:
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的線程的大量切換。
另外,如果要查看中斷次數(shù),可以讀取這個(gè)文件/proc/interrupts:
/proc 實(shí)際上是 Linux 的一個(gè)虛擬文件系統(tǒng),用于內(nèi)核空間與用戶空間之間的通信。/proc/interrupts 就是這種通信機(jī)制的一部分,提供了一個(gè)只讀的中斷使用情況。
watch -d cat /proc/interrupts # 高亮顯示中斷文件的變動(dòng)部分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從中可以觀察到,以下兩個(gè)參數(shù)在不斷變化
- Local timer interrupts
- Rescheduling interrupts 重新調(diào)度中斷(RES),表示喚醒空閑狀態(tài)的CPU來調(diào)度新的任務(wù)運(yùn)行,這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同CPU的機(jī)制
結(jié)論
每秒上下文切換次數(shù)的大小,取決于CPU性能,一般來說,切換穩(wěn)定,數(shù)值從百到萬以內(nèi),都算正常:
- cswch/s 切換多,說明進(jìn)程在等待資源,可能發(fā)生了I/O等其他問題
- nvcswch/sq 切換多,說明進(jìn)程被強(qiáng)制調(diào)度,也就是爭(zhēng)搶CPU,說明CPU有瓶頸
- 中斷次數(shù)多了,說明CPU被中斷程序占用,具體可以分析 /proc/interrupts文件
總結(jié)
以上是生活随笔為你收集整理的平均负载及CPU上下文切换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 汉字转拼音pinyin4
- 下一篇: ORACLE EBS财务科目FLEX F