Linux性能分析的前60000毫秒【轉】

Linux性能分析的前60000毫秒

爲了解決性能問題,你登入了一臺Linux服務器,在最開始的一分鐘內須要查看什麼?html

在Netflix咱們有一個龐大的EC2 Linux集羣,還有很是多的性能分析工具來監控和調查它的性能。其中包括用於雲監控的Atlas,用於實例按需分析的Vector。即便這些工具幫助咱們解決了大多數問題,咱們有時仍是得登入Linux實例,運行一些標準的Linux性能工具來解決問題。java

在這篇文章裏,Netflix Performance Engineering團隊將使用居家常備的Linux標準命令行工具,演示在性能調查最開始的60秒裏要乾的事,linux

最開始的60秒......

運行下面10個命令,你能夠在60秒內就對系統資源的使用狀況和進程的運行情況有大致上的瞭解。無非是先查看錯誤信息和飽和指標,再看下資源的使用量。這裏「飽和」的意思是,某項資源供不該求,已經形成了請求隊列的堆積,或者延長了等待時間。ios

uptime
dmesg | tail
vmstat 1 mpstat -P ALL 1 pidstat 1 iostat -xz 1 free -m sar -n DEV 1 sar -n TCP,ETCP 1 top

有些命令須要你安裝sysstat包。(譯註:指mpstat, pidstat, iostat和sar,用包管理器直接安裝sysstat便可) 這些命令所提供的指標可以幫助你實踐USE方法:這是一種用於定位性能瓶頸的方法論。你能夠以此檢查全部資源(CPU,內存,硬盤,等等)的使用量,是否飽和,以及是否存在錯誤。同時請留意上一次檢查正常的時刻,這將幫助你減小待分析的對象,並指明調查的方向。(譯註:USE方法,就是檢查每一項資源的使用量(utilization)、飽和(saturation)、錯誤(error))git

接下來的章節裏咱們將結合實際例子講解這些命令。若是你想了解更多的相關信息,請查看它們的man page。github

1. uptime

$ uptime
 23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02

這個命令顯示了要運行的任務(進程)數,經過它可以快速瞭解系統的平均負載。在Linux上,這些數值既包括正在或準備運行在CPU上的進程,也包括阻塞在uninterruptible I/O(一般是磁盤I/O)上的進程。它展現了資源負載(或需求)的大體狀況,不過進一步的解讀還有待其它工具的協助。對它的具體數值不用太較真。docker

最右的三個數值分別是1分鐘、5分鐘、15分鐘系統負載的移動平均值。它們共同展示了負載隨時間變更的狀況。舉個例子,假設你被要求去檢查一個出了問題的服務器,而它最近1分鐘的負載遠遠低於15分鐘的負載,那麼你極可能已經撲了個空。vim

在上面的例子中,負載均值最近呈上升態勢,其中1分鐘值高達30,而15分鐘值僅有19。這種現象有許多種解釋,頗有多是對CPU的爭用;該系列的第3個和第4個命令——vmstatmpstat——能夠幫助咱們進一步肯定問題所在。segmentfault

2. dmesg | tail

$ dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0 [...] [1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child [1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB [2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.

這個命令顯示了最新的10個系統信息,若是有的話。注意會致使性能問題的錯誤信息。上面的例子裏就包括對過多佔用內存的某進程的死刑判決,還有丟棄TCP請求的公告。緩存

不要漏了這一步!檢查dmesg老是值得的。

3. 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 st 34 0 0 200889792 73708 591828 0 0 0 5 6 10 96 1 3 0 0 32 0 0 200889920 73708 591860 0 0 0 592 13284 4282 98 1 1 0 0 32 0 0 200890112 73708 591860 0 0 0 0 9501 2154 99 1 0 0 0 32 0 0 200889568 73712 591856 0 0 0 48 11900 2459 99 0 0 0 0 32 0 0 200890208 73712 591860 0 0 0 0 15898 4840 98 1 1 0 0 ^C

vmstat(8),是「virtual memory stat」的簡稱,幾十年前就已經包括在BSD套件之中,一直以來都是居家常備的工具。它會逐行輸出服務器關鍵數據的統計結果。

經過指定1做爲vmstat的輸入參數,它會輸出每一秒內的統計結果。(在咱們當前使用的)vmstat輸出的第一行數據是從啓動到如今的平均數據,而不是前一秒的數據。因此咱們能夠跳過第一行,看看後面幾行的狀況。

檢查下面各列:

r:等待CPU的進程數。該指標能更好地斷定CPU是否飽和,由於它不包括I/O。簡單地說,r值高於CPU數時就意味着飽和。

free:空閒的內存千字節數。若是你數不清有多少位,就說明系統內存是充足的。接下來要講到的第7個命令,free -m,可以更清楚地說明空閒內存的狀態。

si,so:Swap-ins和Swap-outs。若是它們不爲零,意味着內存已經不足,開始動用交換空間的存糧了。

us,sy,id,wa,st:它們是全部CPU的使用百分比。它們分別表示user time,system time(處於內核態的時間),idle,wait I/O和steal time(被其它租戶,或者是租戶本身的Xen隔離設備驅動域(isolated driver domain),所佔用的時間)。

經過相加us和sy的百分比,你能夠肯定CPU是否處於忙碌狀態。一個持續不變的wait I/O意味着瓶頸在硬盤上,這種狀況每每伴隨着CPU的空閒,由於任務都卡在磁盤I/O上了。你能夠把wait I/O看成CPU空閒的另外一種形式,它額外給出了CPU空閒的線索。

I/O處理一樣會消耗系統時間。一個高於20%的平均系統時間,每每值得進一步發掘:也許系統花在I/O的時太長了。

在上面的例子中,CPU基本把時間花在用戶態裏面,意味着跑在上面的應用佔用了大部分時間。此外,CPU平均使用率在90%之上。這不必定是個問題;檢查下「r」列,看看是否飽和了。

4. mpstat -P ALL 1

$ mpstat -P ALL 1 Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU) 07:38:49 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 07:38:50 PM all 98.47 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.78 07:38:50 PM 0 96.04 0.00 2.97 0.00 0.00 0.00 0.00 0.00 0.00 0.99 07:38:50 PM 1 97.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00 07:38:50 PM 2 98.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 07:38:50 PM 3 96.97 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.03 [...]

這個命令顯示每一個CPU的時間使用百分比,你能夠用它來檢查CPU是否存在負載不均衡。單個過於忙碌的CPU可能意味着整個應用只有單個線程在工做。

5. pidstat 1

$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015    _x86_64_    (32 CPU)

07:41:02 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:41:03 PM     0  9 0.00 0.94 0.00 0.94  1 rcuos/0 07:41:03 PM  0  4214 5.66 5.66 0.00 11.32  15 mesos-slave 07:41:03 PM  0  4354 0.94 0.94 0.00 1.89  8 java 07:41:03 PM  0  6521 1596.23 1.89 0.00 1598.11  27 java 07:41:03 PM  0  6564 1571.70 7.55 0.00 1579.25  28 java 07:41:03 PM 60004  60154 0.94 4.72 0.00 5.66  9 pidstat 07:41:03 PM UID PID %usr %system %guest %CPU CPU Command 07:41:04 PM  0  4214 6.00 2.00 0.00 8.00  15 mesos-slave 07:41:04 PM  0  6521 1590.00 1.00 0.00 1591.00  27 java 07:41:04 PM  0  6564 1573.00 10.00 0.00 1583.00  28 java 07:41:04 PM  108  6718 1.00 0.00 0.00 1.00  0 snmp-pass 07:41:04 PM 60004  60154 1.00 4.00 0.00 5.00  9 pidstat ^C

pidstat看上去就像top,不過top的輸出會覆蓋掉以前的輸出,而pidstat的輸出則添加在以前的輸出的後面。這有利於觀察數據隨時間的變更狀況,也便於把你看到的內容複製粘貼到調查報告中。

上面的例子代表,CPU主要消耗在兩個java進程上。%CPU列是在各個CPU上的使用量的總和;1591%意味着java進程消耗了將近16個CPU。

6. iostat -xz 1

$ iostat -xz 1 Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 73.96 0.00 3.73 0.03 0.06 22.21 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util xvda 0.00 0.23 0.21 0.18 4.52 2.08 34.37 0.00 9.98 13.80 5.42 2.44 0.09 xvdb 0.01 0.00 1.02 8.94 127.97 598.53 145.79 0.00 0.43 1.78 0.28 0.25 0.25 xvdc 0.01 0.00 1.02 8.86 127.79 595.94 146.50 0.00 0.45 1.82 0.30 0.27 0.26 dm-0 0.00 0.00 0.69 2.32 10.47 31.69 28.01 0.01 3.23 0.71 3.98 0.13 0.04 dm-1 0.00 0.00 0.00 0.94 0.01 3.78 8.00 0.33 345.84 0.04 346.81 0.01 0.00 dm-2 0.00 0.00 0.09 0.07 1.35 0.36 22.50 0.00 2.55 0.23 5.62 1.78 0.03 [...] ^C

這個命令能夠弄清塊設備(磁盤)的情況,包括工做負載和處理性能。注意如下各項:

r/s,w/s,rkB/s,wkB/s:分別表示每秒設備讀次數,寫次數,讀的KB數,寫的KB數。它們描述了磁盤的工做負載。也許性能問題就是由太高的負載所形成的。

await:I/O平均時間,以毫秒做單位。它是應用中I/O處理所實際消耗的時間,由於其中既包括排隊用時也包括處理用時。若是它比預期的大,就意味着設備飽和了,或者設備出了問題。

avgqu-sz:分配給設備的平均請求數。大於1表示設備已經飽和了。(不過有些設備能夠並行處理請求,好比由多個磁盤組成的虛擬設備)

%util:設備使用率。這個值顯示了設備每秒內工做時間的百分比,通常都處於高位。低於60%一般是低性能的表現(也能夠從await中看出),不過這個得看設備的類型。接近100%一般意味着飽和。

若是某個存儲設備是由多個物理磁盤組成的邏輯磁盤設備,100%的使用率可能只是意味着I/O佔用

請牢記於心,disk I/O性能低不必定是個問題。應用的I/O每每是異步的(好比預讀(read-ahead)和寫緩衝(buffering for writes)),因此不必定會被阻塞並遭受延遲。

7. free -m

$ free -m
             total       used       free     shared    buffers     cached
Mem:        245998  24545  221453  83  59 541 -/+ buffers/cache:  23944 222053 Swap:  0  0 0

右邊的兩列顯示:
buffers:用於塊設備I/O的緩衝區緩存
cached:用於文件系統的頁緩存
它們的值接近於0時,每每致使較高的磁盤I/O(能夠經過iostat確認)和糟糕的性能。上面的例子裏沒有這個問題,每一列都有好幾M呢。

比起第一行,-/+ buffers/cache提供的內存使用量會更加準確些。Linux會把暫時用不上的內存用做緩存,一旦應用須要的時候馬上從新分配給它。因此部分被用做緩存的內存其實也算是空閒內存,第二行以此修訂了實際的內存使用量。爲了解釋這一點, 甚至有人專門建了個網站: linuxatemyram

若是你在Linux上安裝了ZFS,正如咱們在一些服務上所作的,這一點會變得更加迷惑,由於ZFS它本身的文件系統緩存不算入free -m。有時系統看上去已經沒有多少空閒內存可用了,其實內存都待在ZFS的緩存裏呢。

8. sar -n DEV 1

$ sar -n DEV 1 Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)  12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil 12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00 12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00 12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00  12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil 12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00 12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00 12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 ^C

這個命令能夠用於檢查網絡流量的工做負載:rxkB/s和txkB/s,以及它是否達到限額了。上面的例子中,eth0接收的流量達到22Mbytes/s,也即176Mbits/sec(限額是1Gbit/sec)

咱們用的版本中還提供了%ifutil做爲設備使用率(接收和發送二者中的最大值)的指標。咱們也能夠用Brendan的nicstat計量這個值。一如nicstatsar顯示的這個值不必定是對的,在這個例子裏面就沒能正常工做(0.00)。

9. sar -n TCP,ETCP 1

$ sar -n TCP,ETCP 1 Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)  12:17:19 AM active/s passive/s iseg/s oseg/s 12:17:20 AM 1.00 0.00 10233.00 18846.00  12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s 12:17:20 AM 0.00 0.00 0.00 0.00 0.00  12:17:20 AM active/s passive/s iseg/s oseg/s 12:17:21 AM 1.00 0.00 8359.00 6039.00  12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s 12:17:21 AM 0.00 0.00 0.00 0.00 0.00 ^C

這個命令顯示一些關鍵TCP指標的彙總。其中包括:
active/s:本地每秒建立的TCP鏈接數(好比concept()建立的)
passive/s:遠程每秒建立的TCP鏈接數(好比accept()建立的)
retrans/s:每秒TCP重傳次數

主動鏈接數(active)和被動鏈接數(passive)一般能夠用來粗略地描述系統負載。能夠認爲主動鏈接是對外的,而被動鏈接是對內的,雖然嚴格來講不徹底是這個樣子。(好比,一個從localhost到localhost的鏈接)

重傳是網絡或系統問題的一個信號;它多是不可靠的網絡(好比公網)所形成的,也有多是服務器已通過載並開始丟包。在上面的例子中,每秒只建立一個新的TCP鏈接。

10. top

$ top
top - 00:15:40 up 21:56,  1 user, load average: 31.09, 29.87, 29.92 Tasks: 871 total,  1 running, 868 sleeping,  0 stopped,  2 zombie %Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 25190241+total, 24921688 used, 22698073+free,  60448 buffers KiB Swap:  0 total,  0 used,  0 free.  554208 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND  20248 root  20  0 0.227t 0.012t  18748 S  3090 5.2 29812:58 java  4213 root  20  0 2722544  64640  44232 S 23.5 0.0 233:35.37 mesos-slave  66128 titancl+  20  0  24344  2332  1172 R 1.0 0.0 0:00.07 top  5235 root  20  0 38.227g 547004  49996 S 0.7 0.2 2:02.74 java  4299 root  20  0 20.015g 2.682g  16836 S 0.3 1.1 33:14.42 java  1 root  20  0  33620  2920  1496 S 0.0 0.0 0:03.82 init  2 root  20  0  0  0  0 S 0.0 0.0 0:00.02 kthreadd  3 root  20  0  0  0  0 S 0.0 0.0 0:05.35 ksoftirqd/0  5 root  0 -20  0  0  0 S 0.0 0.0 0:00.00 kworker/0:0H  6 root  20  0  0  0  0 S 0.0 0.0 0:06.94 kworker/u256:0  8 root  20  0  0  0  0 S 0.0 0.0 2:38.05 rcu_sched 

top命令包括不少咱們以前檢查過的指標。它適合用來查看相比於以前的命令輸出的結果,負載有了哪些變更。

不能清晰顯示數據隨時間變更的狀況,這是top的一個缺點。相較而言,vmstatpidstat的輸出不會覆蓋掉以前的結果,所以更適合查看數據隨時間的變更狀況。另外,若是你不能及時暫停top的輸出(Ctrl-s暫停,Ctrl-q繼續),也許某些關鍵線索會湮滅在新的輸出中。

在這以後...

 

參考

大牛的博客 Brendan Gregg: Overview
http://www.brendangregg.com/overview.html

超全整理!Linux性能分析工具彙總合集 - 測試 - 恆生研究院
http://rdc.hundsun.com/portal/article/731.html

[譯]Linux性能分析的前60000毫秒 - spacewander - SegmentFault 思否https://segmentfault.com/a/1190000004104493

相關文章
相關標籤/搜索