Linux內存、性能分析詳解

在做雙十一投放紅包項目時,做壓力測試,分析性能問題,用到了一些linux工具,以此做了一些總結:

TOP

啓動 top 
top 的全屏對話模式可分爲3部分:系統信息欄、命令輸入欄、進程列表欄:
top - 20:05:40 up 14 days,  1:49,  2 users,  load average: 0.31, 0.33, 0.60
Tasks: 453 total,   1 running, 452 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.8%us,  0.1%sy,  0.0%ni, 99.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  65864020k total, 17787480k used, 48076540k free,   237748k buffers
Swap:  4194300k total,        0k used,  4194300k free,  4512088k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                               
 21396 root      20   0 42.9g  11g  21m S 88.8 18.5 195:43.89 java                                                                 
   107 root      20   0     0    0    0 S  2.0  0.0   0:21.89 events/8                                                             
     1 root      20   0 19232 1512 1224 S  0.0  0.0   0:01.74 init                                                                 
     2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                             
     3 root      RT   0     0    0    0 S  0.0  0.0   0:00.23 migration/0                                                           
     4 root      20   0     0    0    0 S  0.0  0.0   0:00.32 ksoftirqd/0 


第一部分 -- 最上部的 系統信息欄 : 
第一行(top): 
    “00:11:04”爲系統當前時刻; 
    “3:35”爲系統啓動後到現在的運作時間; 
    “2 users”爲當前登錄到系統的用戶,更確切的說是登錄到用戶的終端數 -- 同一個用戶同一時間對系統多個終端的連接將被視爲多個用戶連接到系統,這裏的用戶數也將表現爲終端的數目; 
    “load average”爲當前系統負載的平均值,後面的三個值分別爲1分鐘前、5分鐘前、15分鐘前進程的平均數,一般的可以認爲這個數值超過 CPU 數目時,CPU 將比較喫力的負載當前系統所包含的進程;
第二行(Tasks): 
    “59 total”爲當前系統進程總數; 
    “1 running”爲當前運行中的進程數; 
    “58 sleeping”爲當前處於等待狀態中的進程數; 
    “0 stoped”爲被停止的系統進程數; 
    “0 zombie”爲被複原的進程數; 
第三行(Cpus): 
分別表示了 CPU 當前的使用率; 
0.3% us 用戶空間佔用CPU百分比 
1.0% sy 內核空間佔用CPU百分比
0.0% ni 用戶進程空間內改變過優先級的進程佔用CPU百分比
98.7% id 空閒CPU百分比
0.0% wa 等待輸入輸出的CPU時間百分比
0.0% hi 
0.0% si
第四行(Mem): 
Mem: 191272k total 物理內存總量
173656k used 使用的物理內存總量
17616k free 空閒內存總量
22052k buffers 用作內核緩存的內存量
Swap: 192772k total 交換區總量
第五行(Swap):
         表示類別同第四行(Mem),但此處反映着交換分區(Swap)的使用情況。通常,交換分區(Swap)被頻繁使用的情況,將被視作物理內存不足而造成的
 0k used 使用的交換區總量
192772k free 空閒交換區總量
123988k cached 緩衝的交換區總量。內存中的內容被換出到交換區,而後又被換入到內存,但使用過的交換區尚未被覆蓋, 該數值即爲這些內容已存在於內存中的交換區的大小。相應的內存再次被換出時可不必再對交換區寫入。 
第二部分 -- 中間部分的內部命令提示欄: 
  top 運行中可以通過 top 的內部命令對進程的顯示方式進行控制。內部命令如下表: 
  s - 改變畫面更新頻率 
  l - 關閉或開啓第一部分第一行 top 信息的表示 
  t - 關閉或開啓第一部分第二行 Tasks 和第三行 Cpus 信息的表示 
  m - 關閉或開啓第一部分第四行 Mem 和 第五行 Swap 信息的表示 
  N - 以 PID 的大小的順序排列表示進程列表(第三部分後述) 
  P - 以 CPU 佔用率大小的順序排列進程列表 (第三部分後述) 
  M - 以內存佔用率大小的順序排列進程列表 (第三部分後述) 
  h - 顯示幫助 
  n - 設置在進程列表所顯示進程的數量 
  q - 退出 top 

第三部分 -- 最下部分的進程列表欄: 
序號  列名  含義  
a  PID  進程id  
b  PPID  父進程id  
c  RUSER  Real user name  
d  UID  進程所有者的用戶id  
e  USER  進程所有者的用戶名  
f  GROUP  進程所有者的組名  
g  TTY  啓動進程的終端名。不是從終端啓動的進程則顯示爲 ?  
h  PR  優先級  
i  NI  nice值。負值表示高優先級,正值表示低優先級  
j  P  最後使用的CPU,僅在多CPU環境 下有意義  
k  %CPU  上次更新到現在的CPU時間佔用百分比  
l  TIME  進程使用的CPU時間總計,單位秒  
m  TIME+  進程使用的CPU時間總計,單位1/100秒  
n  %MEM  進程使用的物理內存 百分比  
o  VIRT  進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES  
p  SWAP  進程使用的虛擬內存中,被換出的大小,單位kb。  
q  RES  進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA  
r  CODE  可執行代碼佔用的物理 內存大小,單位kb  
s  DATA  可執行代碼以外的部分(數據 段+棧)佔用的物理 內存大小,單位kb  
t  SHR  共享內存大小,單位kb  
u  nFLT  頁面錯誤次數  
v  nDRT  最後一次寫入到現在,被修改過的頁面數。  
w  S  進程狀態。
            D =不可中斷的睡眠狀態
            R =運行
            S =睡眠
            T =跟蹤/停止
            Z =殭屍進程  
x  COMMAND  命令名/命令行  
y  WCHAN  若該進程在睡眠,則顯示睡眠中的系統函數名  
z  Flags  任務標誌,參考 sched.h  

默認情況下僅顯示比較重要的  PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND  列。可以通過下面的快捷鍵來更改顯示內容。
更改顯示內容通過 f 鍵可以選擇顯示的內容。按 f 鍵之後會顯示列的列表,按 a-z  即可顯示或隱藏對應的列,最後按回車鍵確定。
按 o 鍵可以改變列的顯示順序。按小寫的 a-z 可以將相應的列向右移動,而大寫的 A-Z  可以將相應的列向左移動。最後按回車鍵確定。
按大寫的 F 或 O 鍵,然後按 a-z 可以將進程按照相應的列進行排序。而大寫的  R 鍵可以將當前的排序倒轉。 

top命令使用過程中,還可以使用一些交互的命令來完成其它參數的功能。這些命令是通過快捷鍵啓動的。
<空格>:立刻刷新。
P:根據CPU使用大小進行排序。
T:根據時間、累計時間排序。
q:退出top命令。
m:切換顯示內存信息。
t:切換顯示進程和CPU狀態信息。
c:切換顯示命令名稱和完整命令行。
M:根據使用內存大小進行排序。
W:將當前設置寫入~/.toprc文件中。這是寫top配置文件的推薦方法。
 
可以看到,top命令是一個功能十分強大的監控系統的工具,對於系統管理員而言尤其重要。但是,它的缺點是會消耗很多系統資源。

free命令

20:09 [[email protected]]$ free
             total       used       free     shared    buffers     cached
Mem:      65864020   17786912   48077108        184     237748    4512092
-/+ buffers/cache:   13037072   52826948
Swap:      4194300          0    4194300
下面是對這些數值的解釋:
total:總計物理內存的大小。
used:已使用多大。
free:可用有多少。
Shared:多個進程共享的內存總額。
Buffers/cached:磁盤緩存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第四行就不多解釋了。

區別:第二行(mem)的used/free與第三行(-/+ buffers/cache) used/free的區別。 這兩個的區別在於使用的角度來看,第一行是從OS的角度來看,因爲對於OS,buffers/cached 都是屬於被使用,所以他的可用內存是48077108 KB,已用內存是17786912 KB,其中包括,內核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached.
第三行所指的是從應用程序角度來看,對於應用程序來說,buffers/cached 是等於可用的,因爲buffer/cached是爲了提高文件讀取的性能,當應用程序需在用到內存的時候,buffer/cached會很快地被回收。
 
free命令是用來查看內存使用情況的主要命令。和top命令相比,它的優點是使用簡單,並且只佔用很少的系統資源。通過-S參數可以使用free命令不間斷地監視有多少內存在使用,這樣可以把它當作一個方便實時監控器。
#free -b -s5
使用這個命令後終端會連續不斷地報告內存使用情況(以字節爲單位),每5秒更新一次。

我們通過free命令查看機器空閒內存時,會發現free的值很小。這主要是因爲,在linux中有這麼一種思想,內存不用白不用,因此它儘可能的cache和buffer一些數據,以方便下次使用。但實際上這些內存也是可以立刻拿來使用的。
所以從應用程序的角度來說,可用內存=系統free memory+buffers+cached。

vmstat

vmstat命令是最常見的Linux/Unix監控工具,可以展現給定時間間隔的服務器的狀態值,包括服務器的CPU使用率,內存使用,虛擬內存交換情況,IO讀寫情況。這個命令是我查看Linux/Unix最喜愛的命令,一個是Linux/Unix都支持,二是相比top,我可以看到整個機器的CPU,內存,IO的使用情況,而不是單單看到各個進程的CPU使用率和內存使用率(使用場景不一樣)。
一般vmstat工具的使用是通過兩個數字參數來完成的,第一個參數是採樣的時間間隔數,單位是秒,第二個參數是採樣的次數,如:
2表示每個兩秒採集一次服務器狀態,1表示只採集一次:
20:10 [[email protected]]$ vmstat 2 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 48077340 237748 4512096    0    0     0     0    1    1  1  0 99  0  0

每個2s報告一次內存情況:
2表示每個兩秒採集一次服務器狀態,1表示只採集一次:
20:11 [[email protected]]$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 48077384 237748 4512096    0    0     0     0    1    1  1  0 99  0  0
 0  0      0 48077088 237748 4512096    0    0     0    14  879  667  0  0 100  0  0
 0  0      0 48077072 237748 4512096    0    0     0     0  966  679  0  0 100  0  0
 0  0      0 48077072 237748 4512096    0    0     0     6  874  627  0  0 100  0  0
r 表示運行隊列(就是說多少個進程真的分配到CPU),我測試的服務器目前CPU比較空閒,沒什麼程序在跑,當這個值超過了CPU數目,就會出現CPU瓶頸了。這個也和top的負載有關係,一般負載超過了3就比較高,超過了5就高,超過了10就不正常了,服務器的狀態很危險。top的負載類似每秒的運行隊列。如果運行隊列過大,表示你的CPU很繁忙,一般會造成CPU使用率很高。
b 表示阻塞的進程,這個不多說,進程阻塞,大家懂的。
swpd 虛擬內存已使用的大小,如果大於0,表示你的機器物理內存不足了,如果不是程序內存泄露的原因,那麼你該升級內存了或者把耗內存的任務遷移到其他機器。
free   空閒的物理內存的大小,我的機器內存總共8G,剩餘3415M。
buff   Linux/Unix系統是用來存儲,目錄裏面有什麼內容,權限等的緩存,我本機大概佔用300多M
cache cache直接用來記憶我們打開的文件,給文件做緩衝,我本機大概佔用300多M(這裏是Linux/Unix的聰明之處,把空閒的物理內存的一部分拿來做文件和目錄的緩存,是爲了提高 程序執行的性能,當程序使用內存時,buffer/cached會很快地被使用。)
si  每秒從磁盤讀入虛擬內存的大小,如果這個值大於0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。我的機器內存充裕,一切正常。
so  每秒虛擬內存寫入磁盤的大小,如果這個值大於0,同上。
bi  塊設備每秒接收的塊數量,這裏的塊設備是指系統上所有的磁盤和其他塊設備,默認塊大小是1024byte,我本機上沒什麼IO操作,所以一直是0,但是我曾在處理拷貝大量數據(2-3T)的機器上看過可以達到140000/s,磁盤寫入速度差不多140M每秒
bo 塊設備每秒發送的塊數量,例如我們讀取文件,bo就要大於0。bi和bo一般都要接近0,不然就是IO過於頻繁,需要調整。
in 每秒CPU的中斷次數,包括時間中斷
cs 每秒上下文切換次數,例如我們調用系統函數,就要進行上下文切換,線程的切換,也要進程上下文切換,這個值要越小越好,太大了,要考慮調低線程或者進程的數目,例如在apache和nginx這種web服務器中,我們一般做性能測試時會進行幾千併發甚至幾萬併發的測試,選擇web服務器的進程可以由進程或者線程的峯值一直下調,壓測,直到cs到一個比較小的值,這個進程和線程數就是比較合適的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個是很耗資源,也要儘量避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導致CPU幹正經事的時間少了,CPU沒有充分利用,是不可取的。
us 用戶CPU時間,我曾經在一個做加密解密很頻繁的服務器上,可以看到us接近100,r運行隊列達到80(機器在做壓力測試,性能表現不佳)。
sy 系統CPU時間,如果太高,表示系統調用時間長,例如是IO操作頻繁。
id  空閒 CPU時間,一般來說,id + us + sy = 100,一般我認爲id是空閒CPU使用率,us是用戶CPU使用率,sy是系統CPU使用率。
wt 等待IO CPU時間。

iostat

iostat主要用於監控系統設備的IO負載情況,iostat首次運行時顯示自系統啓動開始的各項統計信息,之後運行iostat將顯示自上次運行該命令以後的統計信息。用戶可以通過指定統計的次數和時間來獲得所需的統計信息。
iostat -d -k 2
參數 -d 表示,顯示設備(磁盤)使用狀態;
-k某些使用block爲單位的列強制使用Kilobytes爲單位;2表示,數據顯示每隔2秒刷新一次:
20:12 [[email protected]]$ iostat -d -k 2
Linux 2.6.32-573.el6.x86_64 (a02.atm.ad.youku)        11/16/16        _x86_64_        (24 CPU)

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.55         0.24         7.94     288367    9661881

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.00         0.00         0.00          0          0

輸出信息的意義:
tps:該設備每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)。"一次傳輸"意思是"一次I/O請求"。多個邏輯請求可能會被合併爲"一次I/O請求"。"一次傳輸"請求的大小是未知的。
kB_read/s:每秒從設備(drive expressed)讀取的數據量;
kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;
kB_read:讀取的總數據量;
kB_wrtn:寫入的總數量數據量;這些單位都爲Kilobytes。
上面的例子中,我們可以看到磁盤sda以及它的各個分區的統計數據,當時統計的磁盤總TPS是 0.55 ,下面是各個分區的TPS。(因爲是瞬間值,所以總TPS並不嚴格等於各個分區TPS的總和)

指定監控的設備名稱爲sda,該命令的輸出結果和上面命令完全相同。
 iostat -d sda 2
默認監控所有的硬盤設備,現在指定只監控sda。

-x 參數
iostat還有一個比較常用的選項-x,該選項將用於顯示和io相關的擴展數據。

iostat -d -x -k 1 10
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          1.56  28.31  7.80 31.49   42.51    2.92    21.26     1.46     1.16     0.03    0.79   2.62  10.28
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          2.00  20.00 381.00  7.00 12320.00  216.00  6160.00   108.00    32.31     1.75    4.50   2.17  84.20

輸出信息的含義
rrqm/s:每秒這個設備相關的讀取請求有多少被Merge了(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合併Merge);wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了。
rsec/s:每秒讀取的扇區數;
wsec/:每秒寫入的扇區數。
rKB/s:The number of read requests that were issued to the device per second;
wKB/s:The number of write requests that were issued to the device per second;
avgrq-sz 平均請求扇區的大小
avgqu-sz 是平均請求隊列的長度。毫無疑問,隊列長度越短越好。   
await:  每一個IO請求的處理的平均時間(單位是微秒毫秒)。這裏可以理解爲IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了。
         這個時間包括了隊列時間和服務時間,也就是說,一般情況下,await大於svctm,它們的差值越小,則說明隊列時間越短,反之差值越大,隊列時間越長,說明系統出了問題。
svctm    表示平均每次設備I/O操作的服務時間(以毫秒爲單位)。如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁盤性能很好,如果await的值遠高於svctm的值,則表示I/O隊列等待太長,         系統上運行的應用程序將變慢。
%util: 在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閒置,那麼該設備的%util = 0.8/1 = 80%,所以該參數暗示了設備的繁忙程度
。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因爲磁盤的併發能力,所以磁盤使用未必就到了瓶頸)。

-c 參數:iostat還可以用來獲取cpu部分狀態值:
20:15 [[email protected]]$ iostat -c 1 10
Linux 2.6.32-573.el6.x86_64 (a02.atm.ad.youku)        11/16/16        _x86_64_        (24 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.77    0.00    0.12    0.01    0.00   99.10

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.17    0.00    0.00    0.00    0.00   99.83

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.17    0.00    0.04    0.00    0.00   99.79

常見用法
iostat -d -k 1 10         #查看TPS和吞吐量信息(磁盤讀寫速度單位爲KB)
iostat -d -m 2            #查看TPS和吞吐量信息(磁盤讀寫速度單位爲MB)
iostat -d -x -k 1 10      #查看設備使用率(%util)、響應時間(await) iostat -c 1 10 #查看cpu狀態
例如:
ostat -d -k 1 |grep sda10
Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda10            60.72        18.95        71.53  395637647 1493241908
sda10           299.02      4266.67       129.41       4352        132
sda10           483.84      4589.90      4117.17       4544       4076
sda10           218.00      3360.00       100.00       3360        100
sda10           546.00      8784.00       124.00       8784        124
sda10           827.00     13232.00       136.00      13232        136
上面看到,磁盤每秒傳輸次數平均約400;每秒磁盤讀取約5MB,寫入約1MB。
iostat -d -x -k 1
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          1.56  28.31  7.84 31.50   43.65    3.16    21.82     1.58     1.19     0.03    0.80   2.61  10.29
sda          1.98  24.75 419.80  6.93 13465.35  253.47  6732.67   126.73    32.15     2.00    4.70   2.00  85.25
sda          3.06  41.84 444.90 54.08 14204.08 2048.98  7102.04  1024.49    32.57     2.10    4.21   1.85  92.24
可以看到磁盤的平均響應時間<5ms,磁盤使用率>80。磁盤響應正常,但是已經很繁忙了。

備註

測量一個進程佔用了多少內存,linux爲我們提供了一個很方便的方法,/proc目錄爲我們提供了所有的信息,實際上top等工具也通過這裏來獲取相應的信息。
/proc/meminfo 機器的內存使用信息
/proc/pid/maps pid爲進程號,顯示當前進程所佔用的虛擬地址。
/proc/pid/statm 進程所佔用的內存

參考:http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html
http://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858810.html

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