服務器性能調優

一 緒論

Linux性能監控之緒論篇性能調優的目的是找到系統的瓶頸,並且調節系統來設法消除這些瓶頸.我們在監控性能的時候重點在於監視一下子系統:
1.CPU
2.Memory
3.IO
4.Network

但這些系統都是彼此依賴,不能單獨只看其中一個.當一個系統負載過重時往往會引起其它子系統的問題,比如說:
->大量的讀入內存的IO請求(page-in IO)會用完內存隊列;
->大量的網絡流量會造成CPU的過載;
->CPU的高使用率可能正在處理空閒內存隊列;
->大量的磁盤讀寫會消耗CPU和IO資源.

我們測試的系統,總的來說可分爲二類:
第一, IO Bound, 這類系統會大量消耗內存和底層的存儲系統,它並不消耗過多的CPU和網絡資源(除非系統是網絡的).IObound系統消耗CPU資源用來接受IO請求,然後會進入休眠狀態.數據庫通常被認爲是IO bound系統.

第二, CPU Bound,這類系統需要消耗大量的CPU資源.他們往往進行大量的數學計算. 高吞吐量的Web server,Mail Server通常被認爲是CPU Bound系統.

在性能測試中首先要做的是建立基線(Baseline),這樣後續的調整纔會有一個參考標準.值得注意的是,在測試基線的時候,一定要保證系統工作在正常的狀態下.

在Linux上,監視系統的性能的常用工具有:
Tool    Description                               Base            Repository
vmstat all purpose performancetool                yes             yes
mpstat provides statistics perCPU                 no              yes
sar all purpose performance monitoringtool        no              yes
iostat provides diskstatistics                    no              yes
netstat provides networkstatistics                yes             yes
dstat monitoring statisticsaggregator             no              inmost distributions
iptraf traffic monitoringdashboard                no              yes
ethtool reports on Ethernet interface configurationyes            yes

這些工具在Linux的安裝過程中都可以選擇進行安裝。

下面是一個vmstat產生的baseline的例子:
# vmstat 1
procs memory swap io system cpu
r b swpd free buff cache si so bi bo in cs us sy wa id
1 0 138592 17932 126272 214244 0 0 1 18 109 19 2 1 1 96
0 0 138592 17932 126272 214244 0 0 0 0 105 46 0 1 0 99
0 0 138592 17932 126272 214244 0 0 0 0 198 62 40 14 0 45
0 0 138592 17932 126272 214244 0 0 0 0 117 49 0 0 0 100
0 0 138592 17924 126272 214244 0 0 0 176 220 938 3 4 13 80
0 0 138592 17924 126272 214244 0 0 0 0 358 1522 8 17 0 75
1 0 138592 17924 126272 214244 0 0 0 0 368 1447 4 24 0 72
0 0 138592 17924 126272 214244 0 0 0 0 352 1277 9 12 0 79
# vmstat 1
procs memory swap io system cpu
r b swpd free buff cache si so bi bo in cs us sy wa id
2 0 145940 17752 118600 215592 0 1 1 18 109 19 2 1 1 96
2 0 145940 15856 118604 215652 0 0 0 468 789 108 86 14 0 0
3 0 146208 13884 118600 214640 0 360 0 360 498 71 91 9 0 0
2 0 146388 13764 118600 213788 0 340 0 340 672 41 87 13 0 0
2 0 147092 13788 118600 212452 0 740 0 1324 620 61 92 8 0 0
2 0 147360 13848 118600 211580 0 720 0 720 690 41 96 4 0 0
2 0 147912 13744 118192 210592 0 720 0 720 605 44 95 5 0 0
2 0 148452 13900 118192 209260 0 372 0 372 639 45 81 19 0 0
2 0 149132 13692 117824 208412 0 372 0 372 457 47 90 10 0 0


二 CPU篇

首先介紹一下Linux kernel中的調度器(scheduler),調度器負責調度系統中的兩種資源,一是線程,二是中斷。調度器給不同資源不同的優先級。從高到低爲:

1.硬件中斷(HardwareInterrupts--這些請求由硬件觸發,比如磁盤已經完成了讀寫任務或是網卡受到了新的數據包。

2.軟件中斷(SoftwareInterrupts)--這裏指的是維護內核運行的內核態軟件中斷。比如內核的時鐘管理進程。

3.實時進程(Real timethreads)--實時進程比內核本身具備更高的優先級,它可以搶佔內核的CPU時間片,在2.4內核是一個不可搶佔的內核,它中不支持實時程序。

4.內核進程(Kernel threads--包括所以的內核程序。

5.用戶進程(User threads--所有運行在用戶態的進程。

 

關於CPU,有3個重要的概念:上下文切換(context switchs),運行隊列(Run queue)和使用率(utilization)。

上下文切換:

     目前流行的CPU在同一時間內只能運行一個線程,超線程的處理器可以在同一時間運行多個線程(包括多核CPU),Linux內核會把多核的處理器當作多個單獨的CPU來識別。

      一個標準的Linux內核何以支持運行5050000個進程運行,對於普通的CPU,內核會調度和執行這些進程。每個進程都會分到CPU的時間片來運行,當一個進程用完時間片或者被更高優先級的進程搶佔後,它會備份到CPU的運行隊列中,同時其他進程在CPU上運行。這個進程切換的過程被稱作上下文切換。過多的上下文切換會造成系統很大的開銷。

 

運行隊列

      每個CPU都會維持一個運行隊列,理想情況下,調度器會不斷讓隊列中的進程運行。進程不是處在sleep狀態就是runable狀態。如果CPU過載,就會出現調度器跟不上系統的要求,導致可運行的進程會填滿隊列。隊列愈大,程序執行時間就愈長。“load”用來表示運行隊列,用top命令我們可以看到CPU一分鐘,5分鐘和15分鐘內的運行隊列的大小。這個值越大表明系統負荷越大。

 

CPU使用率:

      CPU使用率可分爲一下幾個部分

      UserTime—執行用戶進程的時間百分比;

      SystemTime—執行內核進程和中斷的時間百分比;

      WaitIO—因爲IO等待而使CPU處於idle狀態的時間百分比;

      Idle—CPU處於Idle狀態的時間百分比。

 

關於時間片和動態優先級:

時間片對於CPU來說是很關鍵的參數,如果時間片太長,就會使系統的交互性能變差,用戶感覺不到並行。如果太短,又會造成系統頻繁的上下文切換,使性能下降。對於IOBound的系統來講並不需要太長的時間片,因爲系統主要是IO操作;而對於CPUBound的系統來說需要長的時間片以保持cache的有效性。

每一個進程啓動的時候系統都會給出一個默認的優先級,但在運行過程中,系統會根據進程的運行狀況不斷調整優先級,內核會升高或降低進程的優先級(每次增加或降低5),判斷標準是根據進程處於sleep狀態的時間。IOBound進程大部分時間在sleep狀態,所以內核會調高它的優先級,CPUBound進程會被內核懲罰降低優先級。因此,如果一個系統上即運行IOBound進程,又運行CPUBound進程,我們會發現,IOBound進程的性能不會下降,而CPUBound進程性能會不斷下降。

我們運行一個CPUBound的程序:cpu-hog。用ps命令可以看出它的優先級在不斷下降。

term1#./cpu-hog

term2# while :;do ps -eo pid,ni,pri,pcpu,comm | egrep

'hog|PRI';sleep 1; done

PID NI PRI %CPUCOMMAND

22855 0 20 84.5cpu-hog

PID NI PRI %CPUCOMMAND

22855 0 18 89.6cpu-hog

PID NI PRI %CPUCOMMAND

22855 0 15 92.2cpu-hog

PID NI PRI %CPUCOMMAND

22855 0 15 93.8cpu-hog

   我們運行find命令,是一個IO Bound的程序,可以觀察到它的優先級不斷提高。

term1# find/

term2# while :;do ps -eo pid,ni,pri,pcpu,comm | egrep

'find|PRI';sleep 1; done

PID NI PRI %CPUCOMMAND

23101 0 20 0.0find

PID NI PRI %CPUCOMMAND

23101 0 21 4.0find

PID NI PRI %CPUCOMMAND

23101 0 23 3.5find

PID NI PRI %CPUCOMMAND

23101 0 23 4.3find

PID NI PRI %CPUCOMMAND

23101 0 23 4.2find

PID NI PRI %CPUCOMMAND

23101 0 23 4.4find

      如果同時運行2個程序就可看出明顯的變化

#while :; do ps -eopid,ni,pri,pcpu,comm | egrep'find|hog';

sleep 1;done

23675 0 20 70.9cpu-hog

23676 0 20 5.6find

23675 0 20 69.9cpu-hog

23676 0 21 5.6find

23675 0 20 70.6cpu-hog

23676 0 23 5.8find

23675 0 19 71.2cpu-hog

23676 0 23 6.0find

23675 0 19 71.8cpu-hog

23676 0 23 6.1find

23675 0 18 72.8cpu-hog

23676 0 23 6.2find

23675 0 16 73.2cpu-hog

23676 0 23 6.6find

23675 0 14 73.9cpu-hog

 

三內存篇

       我們首先了解虛擬內存和物理內存:虛擬內存就是採用硬盤來對物理內存進行擴展,將暫時不用的內存頁寫到硬盤上而騰出更多的物理內存讓有需要的進程來用。當這些內存頁需pi要用的時候在從硬盤讀回內存。這一切對於用戶來說是透明的。通常在Linux系統說,虛擬內存就是swap分區。在X86系統上虛擬內存被分爲大小爲4K的頁。

       Linux性能監控每一個進程啓動時都會向系統申請虛擬內存(VSZ),內核同意或者拒就請求。當程序真正用到內存時,系統就它映射到物理內存。RSS表示程序所佔的物理內存的大小。用ps命令我們可以看到進程佔用的VSZ和RSS。

# ps –aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

daemon 2177 0.0 0.2 3352 648 ? Ss 23:03 0:00 /usr/sbin/atd

dbus 2196 0.0 0.5 13180 1320 ? Ssl 23:03 0:00 dbus-daemon-1--sys

root 2210 0.0 0.4 2740 1044 ? Ss 23:03 0:00cups-config-daemon

root 2221 0.3 1.5 6108 4036 ? Ss 23:03 0:02 hald

root 2231 0.0 0.1 2464 408 tty1 Ss+ 23:03 0:00 /sbin/mingettytty1

內核會定期將內存中的數據同步到硬盤,這個過程叫做MemoryPaging。同時內核也要負責回收不用的內存,將他們分給其他需要的進程。PFRA算法(Page Frame reclaimalgorithm)負責回收空閒的內存。算法根據內存頁的類型來決定要釋放的內存頁。有下列4種類型:

1. Unreclaimable – 鎖定的,內核保留的頁面;

2. Swappable – 匿名的內存頁;

3. Syncable – 通過硬盤文件備份的內存頁;

4. Discardable – 靜態頁和被丟棄的頁。

除了第一種(Unreclaimable)之外其餘的都可以被PFRA進行回收。與之相關的進程是kswapd。在kswapd中,有2個閥值,pages_hige和pages_low。當空閒內存頁的數量低於pages_low的時候,kswapd進程就會掃描內存並且每次釋放出32個free pages,直到free page的數量到達pages_high。具體kswapd是如何回收內存的呢?有如下原則:

1. 如果頁未經更改就將該頁放入空閒隊列;

2. 如果頁已經更改並且是可備份迴文件系統的,就理解將內存頁的內容寫回磁盤;

3. 如果頁已經更改但是沒有任何磁盤上的備份,就將其寫入swap分區。

# ps -ef | grep kswapd

root 30 1 0 23:01 ? 00:00:00 [kswapd0]

Linux性能監控在回收內存過程中還有兩個重要的方法,一是LMR(Low on memoryreclaiming),另一個是OMK(Out of MemoryKiller)。當分配內存失敗的時候LMR將會其作用,失敗的原因是kswapd不能提供足夠的空閒內存,這個時候LMR會每次釋放1024個垃圾頁知道內存分配成功。當LMR不能快速釋放內存的時候,OMK就開始其作用,OMK會採用一個選擇算法來決定殺死某些進程。當選定進程時,就會發送信號SIGKILL,這就會使內存立即被釋放。OMK選擇進程的方法如下:

1. 進程佔用大量的內存;

2. 進程只會損失少量工作;

3. 進程具有低的靜態優先級;

4. 進程不屬於root用戶。

Linux性能監控進程管理中另一個程序pdflush用於將內存中的內容和文件系統進行同步,比如說,當一個文件在內存中進行修改,pdflush負責將它寫回硬盤。

# ps -ef | grep pdflush

root 28 3 0 23:01 ? 00:00:00 [pdflush]

root 29 3 0 23:01 ? 00:00:00 [pdflush]

每當內存中的垃圾頁(dirtypage)超過10%的時候,pdflush就會將這些頁面備份回硬盤。這個比率是可以調節的,通過參數vm.dirty_background_ratio。

# sysctl -n vm.dirty_background_ratio

Pdflush同PFRA是獨立運行的,當內核調用LMR時,LMR就觸發pdflush將垃圾頁寫回硬盤

四 IO篇

關於Linux性能監控相信大家已經小有了解,對於IO篇,讓我們先分析一些具體的情況,在這些情況下I/O會成爲系統的瓶頸。我們會用到工具topvmstatiostatsar等。每一個工具的輸出都從不同的方面反映除系統的性能情況。

Linux性能監控情況1:同一時間進行大量的I/O操作

在這種情況時我們會發現CPUwa時間百分比會上升,證明系統的idle時間大部分都是在等待I/O操作。
# vmstat 1
procs -----memory----- ---swap---io---- --system--cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
3 2 0 55452 9236 1739020 0 0 9352 0 2580 8771 20 24 0 57
2 3 0 53888 9232 1740836 0 0 14860 0 2642 8954 23 25 0 52
2 2 0 51856 9212 1742928 0 0 12688 0 2636 8487 23 25 052

從這個輸出我們可以看到CPU50%的時間都在等待I/O操作,我們還可以看到系統的bi值很大,證明系統有大量的I/O請求將磁盤內容讀入內存。

沒有很好的工具能看到到底是哪個進程在進行I/O讀寫。但我們可以通過top命令的輸出來猜測
# top -d 1
top - 19:45:07 up 1:40, 3 users, load average: 6.36, 5.87,4.40
Tasks: 119 total, 3 running, 116 sleeping, 0 stopped, 0zombie
Cpu(s): 5.9% us, 87.1% sy, 0.0% ni, 0.0% id, 5.9% wa, 1.0% hi, 0.0%si
Mem: 2075672k total, 2022668k used, 53004k free, 7156kbuffers
Swap: 2031608k total, 132k used, 2031476k free, 1709372kcached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ nFLT COMMAND
3069 root 5 -10 450m 303m 280m S 61.5 15.0 10:56.68 4562vmware-vmx
3016 root 5 -10 447m 300m 280m S 21.8 14.8 12:22.83 3978vmware-vmx
3494 root 5 -10 402m 255m 251m S 3.0 12.6 1:08.65 3829vmware-vmx
3624 root 5 -10 401m 256m 251m S 1.0 12.6 0:29.92 3747vmware-vmx

top的輸出通過faults進行排序。我們可以看到vmware產生最多的page faults。也就是說它進行了大量的IO操作。

Linux性能監控情況2:管道太小

任何I/O操作都需要一定的時間,而且這些時間對於硬盤來說是確定的,它包含磁盤旋轉的延時RDrotation delay)和磁頭搜索時間DSdisk seek)。RD由磁盤轉速(RPM)決定。RD是磁盤旋轉一週所需時間的一半。如RPM10000.
RPS=RPM/60=166
1/166=0.0006=6ms
 磁盤旋轉一週要6毫秒
RD=6ms/2=3ms

磁盤平均搜索時間是3ms,數據傳輸的平均延時是2ms,這樣一次I/O操作的平均時間是:
3ms+3ms+2ms=8ms
IOPS=1000/8=125
 這塊磁盤的每秒IO數(IOPS)爲125。所以對於10000RPM的磁盤來說它所能承受的IO操作在IOPS120150之間。如果系統的I/O請求超過這個值,就會使磁盤成爲系統的瓶頸。

對與系統而言有兩種不同種類的I/O壓力,連續I/O和隨機I/O

連續I/O常常出現在企業級數據庫這樣的應用中,需要連續的讀取大量數據。這種系統的性能依靠它讀取和移動數據的大小和快慢。我們用iostat來監控,會發現rKB/s,wKB/s會很高。
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/swkB/s avgrq-sz avgqu-sz await svctm %util
/dev/sda 0.00 12891.43 0.00 105.71 0.00 106080.00 0.00 53040.001003.46 1099.43 3442.43 26.49 280.00

從輸出我們看到w/s=105,wKB/s=53040.所以53040/105=505KB perI/O.

對於隨機I/O的系統來說性能的關注點不在搜傳輸數據的大小和速度,而是在磁盤的IOPS。這類系統的I/O請求比較小但是數量很大,如Web服務器和Mail服務器。他們的性能主要依賴每秒鐘可處理的請求數:
# iostat -x 1
avg-cpu: %user %nice %sys %idle
2.04 0.00 97.96 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-szavgqu-sz await svctm %util
/dev/sda 0.00 633.67 3.06 102.31 24.49 5281.63 12.24 2640.82 288.8973.67 113.89 27.22 50.00

從輸出我們看到w/s=102,wKB/s=2640.所以2640/102=23KB perI/O.因此對於連續I/O系統來說我們要關注系統讀取大量數據的能力即KB per request.對於隨機I/O系統我們注重IOPS

 

五 Network篇

網絡中最常見的錯誤就是衝突,由於網絡中目前基本採用交換機環境,因此衝突問題已被消除。但是當網絡流量不斷增大的時候,就會出現丟包,網卡過載等情況。在網絡流量很大的時候我們用sar命令來給出網絡中可能的錯誤:

# sar -n FULL 5 100

Linux 2.6.9-55.ELsmp (sapulpa)06/23/2007

11:44:32 AM IFACE rxpck/s txpck/srxbyt/s txbyt/s rxcmp/s txcmp/s rxmcst/s

11:44:37 AM lo 6.00 6.00 424.40 424.400.00 0.00 0.00

11:44:37 AM eth0 0.00 0.00 0.00 0.000.00 0.00 0.00

11:44:37 AM sit0 0.00 0.00 0.00 0.000.00 0.00 0.00

11:44:32 AM IFACE rxerr/s txerr/scoll/s rxdrop/s txdrop/s txcarr/s rxfram/s rxfifo/s txfifo/s

11:44:37 AM lo 0.00 0.00 0.00 0.00 0.000.00 0.00 0.00 0.00

11:44:37 AM eth0 0.00 0.00 0.00 0.000.00 0.00 0.00 0.00 0.00

11:44:37 AM sit0 0.00 0.00 0.00 0.000.00 0.00 0.00 0.00 0.00

11:44:32 AM totsck tcpsck udpsck rawsckip-frag

11:44:37 AM 297 79 8 0 0

  rxerr/s是接受錯誤率;txerr/s是發送錯誤率;coll/s衝突率;rxdrop/s接受幀丟失率;txdrop/s發送幀丟失率;txcarr/s載波錯誤率;rxfram/s幀排列錯誤;rxfifo/s接受FIFO錯誤;txfifo/s發送FIFO錯誤。從上面輸出看出各種錯誤爲零,證明網絡工作良好。

  總的來說監視網絡性能,我們有遵循一下幾點:

1. 檢查所有網絡接口確保他們都運行在正確的速率;

2. 檢查每塊網卡的吞吐量確保沒有造成過載;

3. 檢查流量的類型確保正確的數據流在傳送。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章