性能分析工具【轉】

Linux Performance Analysis and Tools(Linux性能分析和工具)

分類:

目錄(?)[+]html

摘自:http://my.oschina.NET/greki/blog/336429python

首先來看一張mysql

圖:linux

上面這張神同樣的圖出自國外一個Lead Performance Engineer(Brendan Gregg)的一次分享,幾乎涵蓋了一個系統的方方面面,任何人,若是沒有完善的計算系統知識,網絡知識和操做系統的知識,這張圖中列出的工具,是不可能所有掌握的。ios

出於本人對Linux系統的極大興趣,以及對底層知識的強烈渴望,並做爲檢驗本身基礎知識的一個指標,我決定將這裏的全部工具學習一遍(時間不限),這篇文章將做爲我學習這些工具的學習筆記。儘可能組織得方便本身往後查閱,並但願對別人也有必定幫助。git

這裏全部的工具,均可以經過man 得到它的幫助文檔,這裏只介紹一些常規用法。程序員

注意:文中全部的interval都是指收集數據的間隔時間,times是指採樣次數。例如github

vmstat interval times

將命令中的interval和times替換成數字:sql

vmstat 3 5

上面語句的意思就是每3秒中輸出一次內存統計數據,共輸出5次。數據庫

Tools: Basic & Intermediate

  1. uptime
  2. top
  3. htop
  4. mpstat
  5. iostat
  6. vmstat
  7. dstat
  8. netstat
  9. strace
  10. iotop
  11. pidstat
  12. ps
  13. lsof

vmstat

咱們先看一個vmstat 的例子。用下面的命令讓它每5秒中打印一個報告。

 

能夠用ctrl+c中止vmstat。vmstat的常規用法是vmstat interval times,即每隔interval秒採 樣一次,共採樣times次,若是省略times,則一直採集數據到用戶手動中止。

第一行的值是顯示了自系統啓動以來的平均值,第二行開始展現如今正在發生的狀況,接下來的行會顯示每5秒的間隔內發生了什麼。每一列的含義在頭部,以下所示:

  • procs

r這一列顯示了多少進程正在等待cpu,b列顯示多少進程正在不可中斷的休眠(一般意味着它們在等待IO ,例如磁盤,網絡,用戶輸入,等等)。

  • memory

swapd列顯示了多少塊被換出到了磁盤(頁面交換)。剩下的三個列顯示了多少塊是空閒的(未被使用),多少塊正在被用做緩衝區,以及多少正在被用做操做系統的緩存。

  • swap

這些列顯示頁面交換活動:每秒有多少塊正在被換入(從磁盤)和換出(到磁盤)。它們比監控swpd列重要多了。大部分時間咱們但願看到si 和so 列是0,而且咱們很明確不但願看到每秒超過10個塊。

  • io

這些列顯示了多少塊從塊設備讀取(bi)和寫出(bo)。這一般反映了硬盤I/O。

  • system

這些列顯示了每秒中斷(in)和上下文切換(cs)的數量。除非上下文切換超過100 000次或更多,通常不用擔憂上下文切換。

  • cpu

這些列顯示全部的CPU時間花費在各種操做的百分比,包括執行用戶代碼(非內核),執行系統代碼(內核),空閒以及等待IO。若是正在使用虛擬化,第5列多是st,顯示了從虛擬機中"偷走"的百分比。

內存不足的表現:free memory 急劇減小,回收buffer和cache也無濟於事,大量使用交換分區(swpd),頁面交換(swap)頻繁,讀寫磁盤數量(io)增多,缺頁中斷(in)增多,上下文切換(cs)次數增多,等待IO的進程數(b)增多,大量CPU時間用於等待IO(wa)。

iostat

如今讓咱們轉移到iostat 。默認狀況下,它顯示了與vmstat 相同的CPU 使用信息。咱們一般只對I/O統計感興趣,因此使用下面的命令只展現擴展的設備統計。

 

與vmstat同樣,第一行報告顯示的是自系統啓動以來的平均值,(一般刪掉它節省空間),而後接下來的報告顯示了增量的平均值,每一個設備一行。

有多種選項顯示和隱藏列。官方文檔有點難以理解,所以咱們必須從源碼中挖掘真正顯示的內容是什麼。說明的列信息以下:

爲了看懂Linux的磁盤IO指標,先了解一些常見的縮寫習慣:rq是request,r是read,w是write,qu是queue,sz是size的,a是average,tm是time,svc是service。

  • rrqm/s 和 wrqm/s

    每秒合併的讀和寫請求。"合併的"意味着操做系統從隊列中拿出多個邏輯請求合併爲一個請求到實際磁盤。

  • r/s 和 w/s

    每秒發送到設備的讀和寫請求數。

  • rsec/s 和 wsec/s

    每秒讀和寫的扇區數。有些系統也輸出爲rKB/s和wKB/s ,意味每秒讀寫的千字節數。(iostat -dkx interval times)

  • avgrq-sz

    請求的扇區數。(讀扇區數 + 寫扇區數) / (讀請求次數 + 寫請求次數)

  • avgqu-sz

    在設備隊列中等待的請求數。即隊列的平均長度。

  • await

    每一個IO請求花費的時間,包括在隊列中的等待時間和實際請求(服務)時間。

  • svctm

    實際請求(服務)時間,以毫秒爲單位,不包括排隊時間。

  • %util

    至少有一個活躍請求所佔時間的百分比。更好的說法應該是,服務時間所佔的百分比。以上面的輸出爲例。 一秒中內,讀了2.5次,寫了1.8次,每次請求的實際請求時間(不包括排隊時間)爲6.0ms,那麼總的時間花費爲(2.5+1.8)*6.0ms,即25.8ms,0.0258秒,轉換成百分比再四捨五入就獲得了util的值2.6%。

    %util: When this figure is consistently approaching above 80% you will need to take any of the following actions -

    • increasing RAM so dependence on disk reduces
    • increasing RAID controller cache so disk dependence decreases
    • increasing number of disks so disk throughput increases (more spindles working parallely)
    • horizontal partitioning

下面這個公式能夠計算一個請求在整個請求期間,有多少時間用以等待。當這個值大於50%,說明整個請求期間,花費了更多時間在隊列中等待;若是這個數很大,則應該採起相應措施。

  • (await-svctim)/await*100: The percentage of time that IO operations spent waiting in queue in comparison to actually being serviced. If this figure goes above 50% then each IO request is spending more time waiting in queue than being processed. If this ratio skews heavily upwards (in the >75% range) you know that your disk subsystem is not being able to keep up with the IO requests and most IO requests are spending a lot of time waiting in queue. In this scenario you will again need to take any of the actions above

IO瓶頸的症狀: 1. %util 很高 2. await 遠大於svctm 3. avgqu-sz 比較大

下面解釋了iowait的做用,須要注意的是,高速CPU也可能致使iowait取值較大。

  • %iowait: This number shows the % of time the CPU is wasting in waiting for IO. A part of this number can result from network IO, which can be avoided by using an Async IO library. The rest of it is simply an indication of how IO-bound your application is. You can reduce this number by ensuring that disk IO operations take less time, more data is available in RAM, increasing disk throughput by increasing number of disks in a RAID array, using SSD (Check my post on Solid State drives vs Hard Drives) for portions of the data or all of the data etc

上面的解釋主要參考《高性能MySQL》和這篇博客

cpu 密集型機器

cpu 密集型服務器的vmstat 輸出一般在us 列會有一個很高的值,報告了花費在非內核代碼上的cpu 時鐘;也可能在sy 列有很高的值,表示系統cpu 利用率,超過20% 就足以使人不安了。在大部分狀況下,也會有進程隊列排隊時間(在r列報告的)。下面是一個列子:

 

若是咱們在同一臺及其上觀察iostat 的輸出(再次剔除顯示啓動以來平均值的第一行),能夠發現磁盤利用率低於50%:

 

這臺機器不是IO密集型的,可是依然有至關數量的IO發生,在數據庫服務器中這種狀況不多見。另外一方面,傳統的Web 服務器會消耗掉大量的CPU 資源,可是不多發生IO,因此Web 服務器的輸出不會像這個例子。

IO 密集型機器

在IO密集型工做負載下,CPU花費大量時間在等待IO請求完成。這意味着vmstat 會顯示不少處理器在非中斷休眠(b列)狀態,而且在wa 這一列的值很高,下面是個例子:

 

這臺機器的iostat 輸出顯示硬盤一直很忙:

 

%util的值可能由於四捨五入的錯誤超過100%。什麼跡象意味着機器是IO密集的呢?只要有足夠的緩衝來服務寫請求,即便機器正在作大量的寫操做,也可能能夠知足,可是卻一般意味着硬盤可能會沒法知足讀請求。這聽起來好像違反直覺,可是若是思考讀和寫的本質,就不會這麼認爲了:

  • 寫請求可以緩衝或同步操做。
  • 讀請求就其本質而言都是同步的。固然,程序能夠猜想到可能須要某些數據,並異步地提早讀取(預讀)。不管如何,一般程序在繼續工做前必須獲得它們須要的數據。這就強制讀請求爲同步操做:程序必須阻塞直到請求完成。

想一想這種方式:你能夠發出一個寫請求到緩衝區的某個地方,而後過一會完成。甚至能夠每秒發出不少這樣的請求。若是緩衝區正確工做,而且有足夠的空間,每一個請求均可以很快完成,而且實際上寫到物理硬盤是被從新排序後更有效地批量操做的。然而,沒有辦法對讀操做這麼作————無論多小或多少的請求,都不可能讓硬盤響應說:"這是你的數據,我等一會讀它"。這就是爲何讀須要IO等待是能夠理解的緣由。

發生內存交換的機器

一臺正在發生內存交換的機器可能在swpd 列有一個很高的值,也可能不高。可是能夠看到si 和 so 列有很高的值,這是咱們不但願看到的。下面是一臺內存交換嚴重的機器的vmstat 輸出:

 

空閒的機器

下面是一臺空閒機器上的vmstat輸出。能夠看到idle列顯示CPU是100%的空閒。

 

dstat

dstat 顯示了cpu使用狀況,磁盤io 狀況,網絡發包狀況和換頁狀況。

我的以爲,iostat和vmstat 的輸出雖然詳細,可是不夠直觀,不如dstat 好用。並且,dstat輸出是彩色的,可讀性更強。如今dstat做爲我首選的,查看系統狀態的工具。

dstat使用時,直接輸入命令便可,不用任何參數。也能夠經過指定參數來顯示更加詳細的信息。

dstat -cdlmnpsy

 

iotop

經過iostat和dstat咱們能夠知道系統的當前IO負載,可是IO負載具體是由哪一個進程產生的呢?這時候咱們須要的是iotop.

iotop是一個用來監視磁盤I/O使用情況的top類工具,具備與top類似的UI,其中包括PID、用戶、I/O、進程等相關信息。 iotop使用Python語言編寫而成,要求Python 2.5(及以上版本)和Linux kernel 2.6.20(及以上版本)。使用很是簡單,在此不作過多介紹,詳細信息參見官網:http://guichaz.free.fr/iotop/

這個命令也能夠以非交互的方式使用:

iotop -bod interval

查看每一個進程的IO,也能夠經過pidstat命令,不像iotop,且pidstat還不須要root權限。

pidstat -d interval

pidstat

瞭解系統IO的狀況大多數是經過iostat來獲取的,這個粒度只能精確到每一個設備。一般咱們會想了 解每一個進程,線程層面發起了多少IO,在Linux 2.6.20以前除了用systemtap這樣的工具來實現 是沒有其餘方法的,由於系統沒有暴露這方面的統計。如今能夠經過一個名爲pidstat的工具, 它的使用方法以下:

pidstat -d interval

此外,pidstat 還能夠用以統計CPU使用信息。

pidstat -u interval

統計內存信息:

pidstat -r interval

top

top 命令的彙總區域顯示了五個方面的系統性能信息: 1. 負載:時間,登陸用戶數,系統平均負載 2. 進程:運行,睡眠,中止,殭屍 3. CPU :用戶態,核心態,NICE,空閒,等待IO,中斷等 4. 內存:總量,已用,空閒(系統角度),緩衝,緩存 5. 交換分區:總量,已用,空閒

任務區域默認顯示:進程ID,有效用戶,進程優先級,NICE值,進程使用的虛擬內存,物理內存和共享內存,進程狀態,CPU 佔用率,內存佔用率,累計CPU時間,進程命令行信息。

htop

另外一個更好用的top的替代工具是htop,htop是Linux系統中的一個互動的進程查看器,一個文本模式的應用程序(在控制檯或者X終端中),須要ncurses。

 

與Linux傳統的top相比,htop更加人性化。它可以讓用戶交互式操做,支持顏色主題,可橫向或縱向滾動瀏覽進程列表,並支持鼠標操做。

與top相比,htop有如下優勢:

  • 能夠橫向或縱向滾動瀏覽進程列表,以便看到全部的進程和完整的命令行。
  • 在啓動上,比top 更快。
  • 殺進程時不須要輸入進程號。
  • htop 支持鼠標操做。

參考資料:Linux下取代top的進程管理工具 htop

mpstat

mpstat 用來統計多核處理器中,每個處理器的使用狀況。mpstat使用方法很簡單,常見用法以下:

mpstat -P ALL interval times

不出意外,讀者執行上面的命令,看不出個因此然來,試試在運行下面這條命令的同時,查看mpstat的輸出。

sysbench --test=cpu --cpu-max-prime=20000 run

注意:sysbench是一個基準測試工具,能夠用來測試cpu,io,mutex,oltp等。在Debain系統下, 經過下面的命令安裝:

sudo apt-get install sysbench

netstat

netstat用於顯示與IP、TCP、UDP和ICMP協議相關的統計數據,通常用於檢驗本機各端口的網絡鏈接狀況。

就我本身而言,常用的用法以下:

netstat -npl

上面這條命令能夠查看你要打開的端口是否已經打開,以此來做爲程序是否已經啓動的依據。

netstat 還有不少其餘的用法,在《TCP/IP詳解》一書中,做者喜歡用netstat命令來打印路由表,使用方法以下:

netstat -rn

其中,flag域的解釋以下:

  • U 該路由可用
  • G 該路由是到一個到網關(路由器)。若是沒有設置該標誌,說明目的地址是直接相連的
  • H 該路由是到一個主機
  • D 該路由是由重定向報文建立
  • M 該路由已被重定向報文修改

netstat 也能夠提供系統上的接口信息:

netstat -in

這個命令打印每一個接口的MTU,輸入分組數,輸入錯誤,輸出分組數,輸出錯誤,衝突以及當前的輸出隊列的長度。

ps

最最經常使用的用法

ps aux #BSD
ps -ef #linux

ps 參數太多,具體使用方法,請man ps,下面是兩種相對經常使用的使用方式。

  • 殺掉某一程序的方法。

    ps aux | grep mysqld | grep -v grep |  awk '{ print $2 }' | xargs kill -9
  • 殺掉殭屍進程:

    ps -eal | awk '{ if ($2 == "Z" ){ print $4}}' | xargs kill -9

strace

用我本身的理解來介紹strace:

咱們寫程序,會調用不少庫函數,而這些庫函數,只是對系統調用的封裝,它們最後都會去調用操做系統提供的系統調用,經過系統調用去訪問硬件設備。strace的做用就是顯示出這些調用關係,讓程序員知道調用一個函數,它到底作了些什麼事情。固然,strace 遠比上面的介紹靈活多變。

下面來看一個例子:

查看mysqld 在linux上加載哪一種配置文件,能夠經過運行下面的命令行:

strace -e stat64 mysqld --print-defaults > /dev/null

strace太強大,內容也太多了,我找到一篇比較好的,介紹strace的文章,請點擊這裏

uptime

uptime是最最最最簡單的工具了,可是也有值得討論的地方,那就是它最後輸出的三個數字是怎麼得來的,有什麼含義?

這三個數字的含義分別是1分鐘、5分鐘、15分鐘內系統的平均負荷,關於這些數字的含義和由來,推薦看阮一峯的文章《理解linux系統負荷這裏》。

我想說的是,這三個數字我每天看,時時看,可是我歷來不相信它。

此話怎講呢?我之因此每天看,時時看,是由於我將這三個數字顯示到了tmux 的狀態欄上,因此,我任什麼時候候均可以看到,而不用專門輸入uptime這個命令。

爲何我不相信它呢,由於這幾個數字只能說明有多少線程在等待cpu,若是咱們的一個任務有不少線程,系統負載不是特別高,可是這幾個數字會出奇的高,也就是不能徹底相信uptime的緣由。若是不信,能夠執行下面這條語句,而後再看看uptime的輸出結果。

sysbench --test=mutex --num-threads=1600 --mutex-num=2048                 --mutex-locks=1000000 --mutex-loops=5000 run

運行了5分鐘之後,個人電腦上輸出以下所示。須要強調的是,這個時候電腦一點不卡,看uptime來判斷系統負載,跟聽cpu風扇聲音判斷系統負載同樣。只能做爲線索,不能做爲系統負載很高的依據。

20:32:39 up 10:21,  4 users,  load average: 386.53, 965.37, 418.57

《Linux Performance Analysis and Tools》裏面也說了,This is only useful as a clue. Use other tools to investigate!

lsof

lsof(list open files)是一個列出當前系統打開文件的工具。在linux環境下,任何事物都以 文件的形式存在,經過文件不只僅能夠訪問常規數據,還能夠訪問網絡鏈接和硬件。因此如傳輸 控制協議(TCP)和用戶數據報協議(UDP)套接字等,系統在後臺都爲該應用程序分配了一個文件描 述符,不管這個文件的本質如何,該文件描述符爲應用程序與基礎操做系統之間的交互提供了 通用接口。由於應用程序打開文件的描述符列表提供了大量關於這個應用程序自己的信息,所以 經過lsof工具可以查看這個列表對系統監測以及排錯將是頗有幫助的。

lsof 的使用方法能夠參考這裏。這裏僅列出幾種常見的用法。

  1. 查看文件系統阻塞 lsof /boot

  2. 查看端口號被哪一個進程佔用 lsof -i :3306

  3. 查看用戶打開哪些文件 lsof -u username

  4. 查看進程打開哪些文件 lsof -p 4838

  5. 查看遠程已打開的網絡連接 lsof -i @192.168.34.128

參考資料:

  1. Linux經常使用監控命令介紹
  2. 使用lsof查找打開的文件
相關文章
相關標籤/搜索