運維秘籍:10條命令1分鐘,如何快速分析 Linux效能問題?

Linksla發表於2023-05-16

如果某個Linux有效能問題,你登入之後來排查,第一分鐘內你會使用哪些命令做那些方面的排查?

在 Netflix,我們在雲端有大量的 EC2 例項,有好幾個效能分析工具來監控和排查效能問題。包括全雲監控產品 Atlas 以及例項粒度的 Vector。儘管這些工具可以幫我們解決大部分問題,但有的時候,我們還是要登入例項執行一些標準的Linux命令來輔助排查。

第一分鐘:總結

在這篇文章中,Netflix 的效能工程團隊將會為你展示如何在最初的 60 秒內透過命令列做效能排查,這個過程中,會使用一些標準的 Linux 工具。

在 60 秒內,你可以透過執行以下十個命令來大致瞭解系統資源使用情況和正在執行的程式。尋找錯誤和飽和度指標,然後是資源利用率相關的指標。

飽和度這個詞可能不易理解,大家可以Google一下USE方法,所謂了飽和了,是資源的負載超過其處理能力了,可以表現為請求佇列的長度或等待時間。

uptimedmesg | tailvmstat 1mpstat -P ALL 1pidstat 1iostat -xz 1free -msar -n DEV 1sar -n TCP,ETCP 1top

這就是那10條命令,有些命令需要提前安裝sysstat包,請注意。這些命令暴露的指標資料,將會幫助你完成 USE Method(這是定位效能瓶頸的一個方法論) 分析。包括對 CPU、記憶體、硬碟等各個方面做檢查,檢查利用率、飽和度、錯誤相關的指標。另外還要注意應用排除法,當我們排除了某類資源的問題,也就意味著縮小了排查範圍,有利於後續排障。
以下部分總結了這些命令,並附有來自生產系統的示例。有關這些工具的更多資訊,請參閱它們的使用手冊。

1、uptime

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

這是一種用來快速檢視系統平均負載的方法,它表明了系統中有多少要執行的任務(程式)。在 Linux 系統中,這些數字包含了需要在 CPU 中執行的程式以及正在等待 I/O(通常是磁碟 I/O)的程式。它僅僅是對系統負載的一個粗略展示,稍微看下即可。你還需要其他工具來進一步瞭解具體情況。

這三個數字展示的是一分鐘、五分鐘和十五分鐘內系統的負載總量平均值按照指數比例壓縮得到的結果。從中我們可以看到系統的負載是如何隨時間變化的。比方你在檢查一個問題,然後看到 1 分鐘對應的值遠小於 15 分鐘的值,那麼可能說明這個問題已經過去了,你沒能及時觀察到。

在上面這個例子中, 系統負載在隨著時間增加,因為最近一分鐘的負載值超過了 30,而 15 分鐘的平均負載則只有 19。這樣顯著的差距包含了很多含義,比方 CPU 負載。若要進一步確認的話,則要執行 vmstat 或 mpstat 命令,這兩個命令請參考後面的章節。

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 條。從這些訊息中找一下有沒有Errors,這些Error或許可以幫你定位系統效能問題。上面的例子包含了 oom-killer,以及 TCP 丟棄一個請求。

千萬不要錯過這一步!dmesg 命令永遠值得一試。

3、vmstat 1

$ vmstat 1procs ---------memory---------- ---swap-- -----io---- -system-- ------cpu----- r  b swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st34  0    0 200889792  73708 591828    0    0     0     5    6   10 96  1  3  0  032  0    0 200889920  73708 591860    0    0     0   592 13284 4282 98  1  1  0  032  0    0 200890112  73708 591860    0    0     0     0 9501 2154 99  1  0  0  032  0    0 200889568  73712 591856    0    0     0    48 11900 2459 99  0  0  0  032  0    0 200890208  73712 591860    0    0     0     0 15898 4840 98  1  1  0  0^C

vmstat(8) 是 virtual memory stat 的縮寫,是一種常用工具(幾十年前為 BSD 建立)。它在每一行列印關鍵伺服器統計資訊的摘要。

vmstat的執行引數為1,每秒列印一次,統計最近一秒鐘的情況,不過請忽略第一行,第一行統計的不是前一秒的情況,是統計的OS啟動以來的平均值,對於我們排查問題而言,沒啥幫助。

需要重點檢視的列

  • r:正在執行或等待執行的程式總數。相比 uptime 中的平均負載資料,這個 r 的值不包含 I/O,可以更好的體現 CPU 的飽和情況。如果這個值大於 CPU 的核數,就表示過於飽和了。

  • free:使用 KB 單位統計的空閒記憶體。如果你發現這裡是一長串數字,說明你還有很多記憶體可用 :) 後面我們會介紹  free -m  命令,可以更好的解釋空閒記憶體的情況。

  • si,so:Swap換入換出的量。如果這些值非0,說明你記憶體不夠用嘍。

  • us,sy,id,wa,st:這些是CPU分解值,是針對所有CPU的一個平均值,並非針對某個核心的。us是user time,sy是system time(kernel),id是idle,wa是wait I/O,st是stolen time(虛擬機器才需要關注st)

把使用者態時間和核心態時間相加,可以得知CPU是否繁忙。一個恆定水平的wa值表示I/O方面有效能瓶頸。如果wa很高,idle就會很高,因為CPU一直在等待I/O獲取資料,沒有辦法繼續運算。

系統時間system time對於I/O處理是必要的。一個高的系統時間平均值,比如超過20%,可以進一步探查,也許核心處理I/O的效率很低。

上面的例子中,CPU時間主要花在 user 上面,說明是使用者態的應用程式在佔用 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,可能是某個單執行緒應用導致的。

    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%的值通常會導致效能不佳(應該在等待中看到),儘管這取決於裝置的情況。接近100%的值通常表示飽和。

        如果儲存裝置是一個邏輯磁碟裝置,面向許多後端磁碟,那麼100%的利用率可能只是意味著一些I/O在100%的時間內被處理,然而,後端磁碟可能遠遠沒有飽和,可能能夠處理更多的工作。

        請記住,磁碟I/O效能差並不一定是應用程式的問題。許多技術通常用於非同步執行I/O,這樣應用程式就不會阻塞並直接受到延遲的影響(例如,讀取時的超前讀取和寫入時的緩衝)。

        7、free -m

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

        右側的兩列:

        • buffers:用於塊裝置 I/O 的緩衝區快取

        • cached:用於檔案系統的頁面快取

        通常,我們需要檢查這些值是否接近 0 了,如果快到 0 了可能會導致更高的硬碟 I/O(使用 iostat 做進一步確認)以及更差的效能。上面例子裡的值看起來還不錯,每個都還有很多 MB。

        -/+ buffers/cache  為 used 和 free 記憶體量提供了更直觀的數值。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工具來測量的東西。和nicstat一樣,這很難搞正確,而且在這個例子中似乎不工作(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連線的數量(例如,透過connect())

            • passive/s:每秒遠端啟動的TCP連線的數量(例如,透過accept())

            • retrans/s:每秒的TCP重傳次數

            主動和被動計數通常作為伺服器負載的一個粗略衡量標準:新接受的連線數(被動),以及下游連線數(主動)。姑且可以把主動看作是出站,把被動看作是入站,但這並不嚴格正確(例如,有的時候是本地主機到本地主機)。

            重傳是網路或伺服器問題的標誌;可能是一個不可靠的網路(如公共網際網路),也可能是由於伺服器過載而丟棄資料包。上面的例子顯示每秒鐘只有一個新的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命令的一個缺點是,它很難看到隨時間變化的模式,而像vmstat和pidstat這樣提供滾動輸出的工具可能更清楚。如果你沒有足夠快地暫停輸出(Ctrl-S暫停,Ctrl-Q繼續),螢幕就會清空,那麼間歇性問題的證據也會丟失。

              後續分析

              還有更多的命令和方法,你可以應用這些命令和方法來深入研究。請看Brendan在2015年Velocity上的Linux效能工具教程,它透過40多個命令,涵蓋了可觀察性、基準測試、調優、靜態效能調優、剖析和跟蹤。

              來源:本文轉自公眾號 SRETalk。


              來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70013542/viewspace-2952269/,如需轉載,請註明出處,否則將追究法律責任。

              相關文章