2012年2月9日 星期四

Linux性能監控工具


1 概述篇
針對四大方向
CPU
Memory
IO
Network
基本參考標準
# 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


安裝監控工具  yum -y install sysstat
1.1. 監控系統性能工具
安裝監控工具  yum -y install sysstat
1.1. 監控系統性能工具Tool
Description
Base
Repository
vmstat
all purpose performance tool
yes
yes
mpstat
provides statistics per CPU
no
yes
sar
all purpose performance monitoring tool
no
yes
iostat
provides disk statistics
no
yes
netstat
provides network statistics
yes
yes
dstat
monitoring statistics aggregator
no
in most distributions
iptraf
traffic monitoring dashboard
no
yes
netperf
Network bandwidth tool
no
In some distributions
ethtool
reports on Ethernet interface configuration
yes
yes
iperf
Network bandwidth tool
no
yes
tcptrace
Packet analysis tool
no
yes
strace
查看相關進程讀寫的資料
2 CPU
CPU
調度優先順序
Interrupts(
中斷)高於Kernel(System) Processes(內核處理過程)高於User Processes(使用者進程)
上下文切換
Linux
內核的系統在一個雙核心處理器上,是報告顯示為兩個獨立的處理器.
一個執行緒要麼就是獲得時間額度或已搶先獲得一些具有較高優先順序(比如硬體中斷),其中較高優先順序的執行緒將從區域重新放置回處理器的佇列中.這種執行緒的轉換關係就是我們提到的上下文切換.
每次內核的上下文切換,資源被用於關閉在CPU寄存器中的執行緒和放置在佇列中.系統中越多的上下文切換,在處理器的調度管理下,內核將得到更多的工作.
運行佇列
每個CPU 都維護一個執行緒的運行佇列
CPU
利用率
User Time(
譯注:使用者進程時間)
System Time(
譯注:內核執行緒以及中斷時間)
Wait IO(
譯注:IO 請求等待時間)
Idle(
譯注:空閒)
CPU 性能監控
Run Queues -
每個處理器應該運行佇列不超過1-3個執行緒.
Run Queues -
每個處理器應該運行佇列不超過1-3個執行緒.例子,一個雙核處理器應該運行佇列不要超過6 個執行緒。
CPU Utiliation -
如果一個CPU 被充分使用,利用率分類之間均衡的比例應該是:
65% - 70% User Time
30% - 35% System Time
0% - 5%   Idle Time
Context Switches -
上下文切換的數目直接關係到CPU 的使用率,如果CPU 利用率保持在上述均衡狀態時,大量的上下文切換是正常的.
vmstat 工具的使用
vmstat
運行1秒間隔的示例:
# vmstat 1
procs ———–memory———- —swap– —–io—-  –system–        —-cpu—-
r  b   swpd   free   buff  cache        si      so    bi    bo   in    cs us sy id wa
0  0 104300  16800  95328  72200    0    0     5    26    7    14  4  1 95  0
0  0 104300  16800  95328  72200    0    0     0    24 1021    64  1  1 98  0
0  0 104300  16800  95328  72200    0    0     0     0 1009    59  1  1 98  0

Field
Description
r
The amount of threads in the run queue. These are threads that are runnable, but the CPU is not available to execute them. 當前運行佇列中執行緒的數目.代表執行緒處於可運行狀態,CPU 還未能執行.
b
This is the number of processes blocked and waiting on IO requests to finish. 當前進程阻塞並等待IO 請求完成的數目
in
This is the number of interrupts being processed. 當前中斷被處理的數目
cs
This is the number of context switches currently happening on the system. 當前kernel system,發生上下文切換的數目
us
This is the percentage of user CPU utilization. CPU 利用率的百分比
sys
This is the percentage of kernel and interrupts utilization. 內核和中斷利用率的百分比
wa
This is the percentage of idle processor time due to the fact that ALL runnable threads are blocked waiting on IO. 所有可運行狀態執行緒被阻塞在等待IO 請求的百分比
id
This is the percentage of time that the CPU is completely idle. CPU 閒置時間的百分比


mpstat 工具的使用
mpstat
命令給出的CPU 利用率統計值大致和 vmstat 一致,但是 mpstat 可以給出基於單個處理器的統計值.
# mpstat –P ALL 1
Linux 2.4.21-20.ELsmp (localhost.localdomain)   05/23/2006
05:17:31 PM  CPU   %user   %nice %system   %idle    intr/s
05:17:32 PM  all    0.00    0.00    3.19   96.53     13.27
05:17:32 PM    0    0.00    0.00    0.00  100.00      0.00
05:17:32 PM    1    1.12    0.00   12.73   86.15     13.27
05:17:32 PM    2    0.00    0.00    0.00  100.00      0.00
05:17:32 PM    3    0.00    0.00    0.00  100.00      0.00
3 記憶體篇
Virtual Memory Pages
X86架構中,每個虛擬記憶體頁為 4KB
記憶體分頁是指內核會定期將記憶體中的資料同步到硬碟,這個過程就是Memory Paging
PFRA
就是OS 內核用來回收並釋放記憶體空間的演算法.PFRA 選擇哪個記憶體頁被釋放是基於記憶體頁類型的.頁類型有以下幾種:
Unreclaimable –
鎖定的,內核保留的頁面
Swappable –
匿名的記憶體頁
Syncable –
通過硬碟檔案備份的記憶體頁
Discardable –
靜態頁和被丟棄的頁
除了第一種(Unreclaimable)之外其餘的都可以被PFRA進行回收.
kswapd
kswapd
進程負責確保記憶體空間總是在被釋放中.它監控內核中的pages_highpages_low閥值.如果空閒記憶體的數值低於 pages_low,則每次 kswapd 進程啟動掃描並嘗試釋放32free pages.並一直重複這個過程,直到空閒記憶體的數值高於 pages_high.
kswapd 進程完成以下幾個操作:
如果該頁處於未修改狀態,則將該頁放置回空閒列表中。
如果該頁處於已修改狀態並可備份回檔案系統,則將頁內容寫入到磁片。
如果該頁處於已修改狀態但沒有任何磁片備份,則將頁內容寫入到swap device
4 IO
磁片I/O 子系統是Linux 系統中最慢的部分
Linux
內核就是要最低程度的降低I/O .
# /usr/bin/time -v date
Linux,類似多數的UNIX 系統,使用一個虛擬記憶體層來映射硬體位址空間.當一個進程被啟動,內核先掃描CPU caches和實體記憶體.如果進程需要的資料在這2個地方都沒找到,就需要從磁片上讀取,此時內核過程就是major page fault(MPF).MPF 要求磁片子系統檢索頁並緩存進RAM.
一旦記憶體頁被映射進記憶體的buffer cache(buff),內核將嘗試從記憶體中讀取或寫入,此時內核過程就是minor page fault(MnPF).與在磁片上操作相比,MnPF 通過反復使用記憶體中的記憶體頁就大大的縮短了核心程式的時間.
Linux 內核中,memory pages3,分別是:
1,Read Pages -
這些頁通過MPF 從磁片中讀入,而且是唯讀.這些頁存在於Buffer Cache中以及包括不能夠修改的靜態檔,二進位檔案,還有庫檔.當內核需要它們時,將讀取到記憶體中.如果記憶體不足,內核將釋放它們回空閒列表中.程式再次請求時,則通過MPF 再次讀回記憶體.
2,Dirty Pages -
這些頁是內核在記憶體中已經被修改過的資料頁.當這些頁需要同步回磁片上,pdflush 負責寫回磁片.如果記憶體不足,kswapd (pdflush 一起)將這些頁寫回到磁片上並釋放更多的記憶體.
3,Anonymous Pages -
這些頁屬於某個進程,但是沒有任何磁片檔和它們有關.他們不能和同步回磁片.如果記憶體不足,kswapd 將他們寫入swap 分區上並釋放更多的記憶體(”swapping” pages).
監控 I/O
每個I/O 請求到磁片都需要若干時間.主要是因為磁片的盤邊必須旋轉,機頭必須尋道.磁片的旋轉常常被稱為”rotational delay”(RD),機頭的移動稱為”disk seek”(DS).一個I/O 請求所需的時間計算就是DS加上RD.磁片的RD 基於設備自身RPM 單位值(譯注:RPM Revolutions Perminute的縮寫,是轉/每分鐘,代表了硬碟的轉速).一個RD 就是一個碟片旋轉的半圓.如何計算一個10K RPM設備的RD 值呢:
10000 RPM / 60 seconds (10000/60 = 166 RPS)
轉換為 166分之1 的值(1/166 = 0.006 seconds/Rotation)
單位轉換為毫秒(6 MS/Rotation)
旋轉半圓的時間(6/2 = 3MS) 也就是 RD
加上平均3 MS 的尋道時間 (3MS + 3MS = 6MS)
加上2MS 的延遲(6MS + 2MS = 8MS)
1000 MS / 8 MS (1000/8 = 125 IOPS)
每次應用程式產生一個I/O,10K RPM磁片上都要花費平均 8MS.在這個固定時間裡,磁片將盡可能且有效率在進行讀寫磁片.IOPS 可以計算出大致的I/O 請求數,10K RPM 磁片有能力提供120-150 IOPS.評估IOPS 的效能,可用每秒讀寫I/O 位元組數除以每秒讀寫IOPS 數得出.
結論
CPU 有等待I/O 情況時,那說明磁片處於超負荷狀態.
計算你的磁片能夠承受多大的IOPS .
確定你的應用是屬於隨機或者順序讀取磁片.
監控磁片慢需要比較wait time(await) service time(svctm).
監控swap 和系統磁碟分割,要確保virtual memory不是檔案系統I/O 的瓶頸.
5 網路(Network)篇
iptraf
工具(http://iptraf.seul.org),提供了每個網卡輸送量的儀錶盤.
#iptraf -d eth0
5.1. Monitoring for Network Throughput
http://img1.51cto.com/attachment/201102/101900360.gif

案例學習 - 性能監控之循序漸進
# vmstat 1 10
procs memory swap io system cpu
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 249844 19144 18532 1221212 0 0 7 3 22 17 25 8 17 18
0 1 249844 17828 18528 1222696 0 0 40448 8 1384 1138 13 7 65 14
0 1 249844 18004 18528 1222756 0 0 13568 4 623 534 3 4 56 37
2 0 249844 17840 18528 1223200 0 0 35200 0 1285 1017 17 7 56 20
分析:
不會是記憶體不足導致,因為swapping 始終沒變化(si so).儘管空閒記憶體不多(free),swpd 也沒有變化.
CPU
方面也沒有太大問題,儘管有一些運行佇列(procs r),但處理器還始終有50% 多的idle(CPU id).
有太多的上下文切換(cs)以及disk blockRAM中被讀入(bo).
CPU
還有平均20% I/O 等待情況.
從以上總結出,這是一個I/O 瓶頸.
# iostat -x 1
Linux 2.4.21-40.ELsmp (mail.example.com) 03/26/2007
avg-cpu: %user %nice %sys %idle
30.00 0.00 9.33 60.67

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
/dev/sda 7929.01 30.34 1180.91 14.23 7929.01 357.84 3964.50 178.92 6.93 0.39 0.03 0.06 6.69
/dev/sda1 2.67 5.46 0.40 1.76 24.62 57.77 12.31 28.88 38.11 0.06 2.78 1.77 0.38
/dev/sda2 0.00 0.30 0.07 0.02 0.57 2.57 0.29 1.28 32.86 0.00 3.81 2.64 0.03
/dev/sda3 7929.01 24.58 1180.44 12.45 7929.01 297.50 3964.50 148.75 6.90 0.32 0.03 0.06 6.68

分析:
看上去只有/dev/sda3 分區很活躍,其他分區都很空閒.
差不多有1200 IOPS,磁片本身是支援200 IOPS左右(譯注:參考之前的IOPS 計算公式).
有超過2,實際上沒有一個讀磁片(rkb/s).這和在vmstat 看到有大量I/O wait是有關係的.
大量的read IOPS(r/s)和在vmstat 中大量的上下文是匹配的.這說明很多讀操作都是失敗的.
結論:
從以上總結出,部分應用程式帶來的讀請求,已經超出了I/O 子系統可處理的範圍.
使用top 來查找系統最活躍的應用程式
# top -d 1
11:46:11 up 3 days, 19:13, 1 user, load average: 1.72, 1.87, 1.80
176 processes: 174 sleeping, 2 running, 0 zombie, 0 stopped
CPU states: cpu user nice system irq softirq iowait idle
total 12.8% 0.0% 4.6% 0.2% 0.2% 18.7% 63.2%
cpu00 23.3% 0.0% 7.7% 0.0% 0.0% 36.8% 32.0%
cpu01 28.4% 0.0% 10.7% 0.0% 0.0% 38.2% 22.5%
cpu02 0.0% 0.0% 0.0% 0.9% 0.9% 0.0% 98.0%
cpu03 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 100.0%
Mem: 2055244k av, 2032692k used, 22552k free, 0k shrd, 18256k buff
1216212k actv, 513216k in_d, 25520k in_c
Swap: 4192956k av, 249844k used, 3943112k free 1218304k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14939 mysql 25 0 379M 224M 1117 R 38.2 25.7% 15:17.78 mysqld
4023 root 15 0 2120 972 784 R 2.0 0.3 0:00.06 top
1 root 15 0 2008 688 592 S 0.0 0.2 0:01.30 init
2 root 34 19 0 0 0 S 0.0 0.0 0:22.59 ksoftirqd/0
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
4 root 10 -5 0 0 0 S 0.0 0.0 0:00.05 events/0
從以上總結出,似乎就只有mysql 進程在請求資源,因此可以推論它就是導致問題的關鍵.
現在已經確定是mysql 在發出讀請求,使用strace 來檢查它在讀請求什麼.
# strace -p 14939
Process 14939 attached - interrupt to quit
read(29, “\3\1\237\1\366\337\1\222%\4\2\0\0\0\0\0012P/d”, 20) = 20
read(29, “ata1/strongmail/log/strongmail-d”…, 399) = 399
_llseek(29, 2877621036, [2877621036], SEEK_SET) = 0
read(29, “\1\1\241\366\337\1\223%\4\2\0\0\0\0\0012P/da”, 20) = 20
read(29, “ta1/strongmail/log/strongmail-de”…, 400) = 400
從以上總結出,所有的讀IOPS 都是mysql 進程在執行某些讀查詢時產生的.
使用mysqladmin 命令,來查找是哪個慢查詢導致的.
# ./mysqladmin -pstrongmail processlist
+—-+——+———–+————+———+——+———-+—————————————-
| Id | User | Host | db | Command | Time | State | Info
+—-+——+———–+————+———+——+———-+—————————————-
| 1 | root | localhost | strongmail | Sleep | 10 | |
| 2 | root | localhost | strongmail | Sleep | 8 | |
| 3 | root | localhost | root | Query | 94 | Updating | update `failures` set
`update_datasource`=
Y where database_id=32 and update_datasource=N and |
| 14 | root | localhost | | Query | 0 | | show processlist
分析:
MySQL
資料庫裡,似乎在不斷的運行table update查詢.
基於這個update 查詢,資料庫是對所有的table 進行索引.
結論:
從以上總結出,MySQL裡這些update 查詢問題,都是在嘗試對所有table 進行索引.這些產生的讀請求正是導致系統性能下降的原因.

沒有留言: