分析CPU性能
top命令提供了監控CPU性能的基本功能, 如果需要更加深入的挖掘CPU的性能問題, top所提供的信息不足以做到. 由於大多數人認爲CPU性能是體現服務器性能的主要因素, 所以在遇到性能問題時, 通常會首先查看CPU的性能來分析服務器的性能問題. 但事實上, 很多情況不是這樣的,性能問題可能是由跟CPU相關的其他因素引起的, 比如CPU等待I/O資源.對於下面兩個task:
Task 1:
dd if=/dev/urandom of=/dev/null
Task 2:
#!/bin/bash COUNTER=0 while true do dd if=/dev/urandom of=/root/file.$COUNTER bs=1M count=1 COUNTER=$(( COUNTER + 1 )) [ COUNTER = 1000 ] && exit done
執行Task 1和Task 2後, sy都會增高, 但是執行Task 2時, wa也會增高, 這說明Task 1和Task 2都會使sy增高, 但是Task 2有時需要等待I/O資源, 所以wa也會增高.
理解CPU性能
爲了監控CPU到底在做什麼, 需要深入理解Linux內核是怎樣工作的, 其中一個重要的組件是運行時隊列(run queue), 每個CPU核有一個運行時隊列, 在CPU爲進程提供服務時, 進程需要首先進入運行時隊列等待CPU分配CPU時間. 運行隊列裏包括可運行的進程(runnable process)和被阻擋的進程(blocked process). Linux的scheduler根據進程的優先級決定哪個runnable process運行, blocked process不會競爭CPU時間. top命令的load arverage是所有runnable process和blocked process的負載的總體概述. 如果需要查看哪些進程處於runnable和blocked狀態, 可以通過vmstat來查看, 如:
[root@rdhl ~]# vmstat 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 0 3747904 15492 27980 0 0 767 3 28 17 0 1 98 1 0
上下文切換和中斷
在多任務操作系統中, Linux內核不斷在不同進程之間進行上下文切換, 這種上下文切換需要CPU保存舊進程的上下文信息以及檢索上下文信息給新進程, 因此上下文切換對CPU的性能代價是很高的. 減少上下文切換帶來的性能問題最好的方法是減少上下文切換的次數, 在多核CPU架構中可以實現, 但是需要確保進程被鎖定在指定CPU核上來阻止上下文切換. Linux進程調度器並不是進程發生上下文切換的唯一原因, 另一個導致上下文切換髮生的原因是硬件中斷(hardware interrupts). 進程調度器使用時鐘中斷(timer interrupt)保證每個進程能獲取公平的CPU時間. 正常情況下上下文切換的次數應該小於時鐘中斷的次數, 如果發現上下文切換次數比時鐘中斷次數多, 這種負載可能是由系統需要處理很多I/O或者長時間高強度系統調用引起. 因此瞭解時鐘中斷和上下文切換的關係對找到引起系統性能問題的原因提供線索. 使用vmstat -s可以查看系統上下文切換和時鐘中斷次數, 這對查看高數量的上下文切換和IOWAIT的組合非常有幫助, 通過這可以判定系統試着做大量的寫操作, 但是不能. 如下是vmstat -s的輸出例子:
[root@rdhl ~]# vmstat -s 3924700 total memory 218964 used memory 32152 active memory 43332 inactive memory 3705736 free memory 22400 buffer memory 31492 swap cache 4063224 total swap 0 used swap 4063224 free swap 7643 non-nice user cpu ticks 0 nice user cpu ticks 1390112 system cpu ticks 15353492 idle cpu ticks 110105 IO-wait cpu ticks 0 IRQ cpu ticks 185 softirq cpu ticks 0 stolen cpu ticks 84007231 pages paged in 333713 pages paged out 0 pages swapped in 0 pages swapped out 16203245 interrupts 2121904 CPU context switches 1395818922 boot time 5780 forks
另一個查看CPU性能的指標是中斷數, 中斷數可以從/proc/interrupts查看,/pro/interrupts包含每種類型的中斷被處理的次數. 如果中斷數很高, 那表示Linux內核花很多時間處理中斷而導致只有少部分時間處理其他進程.
[root@rdhl ~]# cat /proc/interrupts CPU0 CPU1 0: 142 0 IO-APIC-edge timer 1: 7 1 IO-APIC-edge i8042 3: 1 0 IO-APIC-edge 4: 1 0 IO-APIC-edge 7: 0 0 IO-APIC-edge parport0 8: 0 0 IO-APIC-edge rtc0 9: 0 0 IO-APIC-fasteoi acpi 12: 108 2 IO-APIC-edge i8042 14: 0 0 IO-APIC-edge ata_piix 15: 107 1 IO-APIC-edge ata_piix 24: 0 0 PCI-MSI-edge pciehp 25: 0 0 PCI-MSI-edge pciehp 26: 0 0 PCI-MSI-edge pciehp 27: 0 0 PCI-MSI-edge pciehp 28: 0 0 PCI-MSI-edge pciehp 29: 0 0 PCI-MSI-edge pciehp 30: 0 0 PCI-MSI-edge pciehp 31: 0 0 PCI-MSI-edge pciehp 32: 0 0 PCI-MSI-edge pciehp 33: 0 0 PCI-MSI-edge pciehp 34: 0 0 PCI-MSI-edge pciehp 35: 0 0 PCI-MSI-edge pciehp 36: 0 0 PCI-MSI-edge pciehp 37: 0 0 PCI-MSI-edge pciehp 38: 0 0 PCI-MSI-edge pciehp 39: 0 0 PCI-MSI-edge pciehp 40: 0 0 PCI-MSI-edge pciehp 41: 0 0 PCI-MSI-edge pciehp 42: 0 0 PCI-MSI-edge pciehp 43: 0 0 PCI-MSI-edge pciehp 44: 0 0 PCI-MSI-edge pciehp 45: 0 0 PCI-MSI-edge pciehp 46: 0 0 PCI-MSI-edge pciehp 47: 0 0 PCI-MSI-edge pciehp 48: 0 0 PCI-MSI-edge pciehp 49: 0 0 PCI-MSI-edge pciehp 50: 0 0 PCI-MSI-edge pciehp 51: 0 0 PCI-MSI-edge pciehp 52: 0 0 PCI-MSI-edge pciehp 53: 0 0 PCI-MSI-edge pciehp 54: 0 0 PCI-MSI-edge pciehp 55: 0 0 PCI-MSI-edge pciehp 56: 1468 667997 PCI-MSI-edge vmw_pvscsi 57: 367182 0 PCI-MSI-edge eth0-rxtx-0 58: 13 115039 PCI-MSI-edge eth0-rxtx-1 59: 0 0 PCI-MSI-edge eth0-event-2 NMI: 0 0 Non-maskable interrupts LOC: 13249018 2561591 Local timer interrupts SPU: 0 0 Spurious interrupts PMI: 0 0 Performance monitoring interrupts IWI: 0 0 IRQ work interrupts RES: 35986 18866 Rescheduling interrupts CAL: 298172 228 Function call interrupts TLB: 1052 2847 TLB shootdowns TRM: 0 0 Thermal event interrupts THR: 0 0 Threshold APIC interrupts MCE: 0 0 Machine check exceptions MCP: 285 285 Machine check polls ERR: 0 MIS: 0
使用vmstat
雖然top能監控CPU的大部分信息, 但是不能提供更加詳細的CPU信息, 而vmstat可以堪當此任. vmstat有兩種使用方式, 一種是sample mode, 在這種方式中, vmstat每個一段時間獲取當前系統信息, 如每隔3秒執行一次, vmstat 3. 另一種是加-s選項, 在這種方式中, vmstat獲取從系統啓動後的系統統計信息, 除了CPU信息, 也包含memory, I/O, swap等.
cs | 上下文切換次數. |
us | CPU花在用戶空間的時間百分比. |
sy | CPU花在系統空間的時間百分比. |
id | CPU空閒百分比. |
wa | CPU等待I/O的時間百分比. |