1. 程式人生 > >通過Vmstat診斷虛擬記憶體找出記憶體IO瓶頸

通過Vmstat診斷虛擬記憶體找出記憶體IO瓶頸

當你的Windows連續開機一個星期時,你是不是發現機器特別慢,點啥啥不開。但是你去看資源管理器的又發現記憶體佔用也沒有到90%,CPU也沒跑滿。那為什麼這個時候會那麼卡呢?

其中一個原因就是由於長期使用機器且沒有關機,導致記憶體中快取了大量的資料。由於系統的虛擬記憶體管理,當記憶體使用達到一定程度時,系統會將記憶體中 的資料交換到硬碟中,也就是Windos的虛擬記憶體,在Linux中叫Swap分割槽。此時如果要使用交換到硬碟上的資料,那麼系統首先要把記憶體中最遠最久沒有 使用的資料交換到硬碟,再把硬碟中需要的資料載入到記憶體,然後才可以跑邏輯,這樣就造成了“點啥啥不開”的殘像了。

那麼這樣的情況會不會發生在我們的Server端Linux上呢?答案當然是肯定的。而且一旦該情況發生,有可能產生雪崩效應,一下就把伺服器弄回老家了。 這裡的典型案例就有云風大大遇到的

Redis轉儲。又或者可以自己手寫一個無限分配 記憶體並使用的例子。然後靜靜等待系統掛掉的那一刻。

那麼什麼時候會發生這樣的情況?或者說當我們的系統表現出什麼的症狀時我們要考慮這樣的情況?如何進行確診?

一般當系統頻繁的需要新記憶體時可能發生這樣的情況,如頻繁的讀檔案而不釋放、網路接收大量檔案寫磁碟(寫磁碟跟不上記憶體從網路接收的量)。此時我們的系統 對外相應速度會急劇下降但是CPU又沒有跑滿。這時我們就應該考慮是不是虛擬記憶體頻繁交換的問題了。通過使用vmstat可以幫助我們來確診是不是這個原因。

1. vmstat輸出

裸奔執行vmstat命令,可以看到一行輸出。該行輸出內容表示的自系統最近啟動後虛擬記憶體和CPU的平均情況。 在輸出的第一行我們稱之為表頭。依次包含了:

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----

幾個欄位,第二行我們稱之為子表頭,依次包含了:

 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

其意義分別為:

  1. procs : 使用記憶體IO的程序統計

    • r : 獲取了IO資源而等待cpu執行的程序數目
    • b : 因為等待IO資源而阻塞休眠的程序數目
  2. memory: 虛擬記憶體相關統計

    • swpd : 用掉的虛擬記憶體大小。也就是交換分割槽內用掉的大小
    • free : 空閒的記憶體大小。
    • buff : 被用作系統buffer的大小。比如write系統呼叫的時候,系統不會立馬寫磁碟,而是先緩衝到buffer中然後在合適的時候寫入磁碟。
    • cache : 被用作系統cache的大小。

這裡,free的大小表示一定可以使用的大小,即malloc不會出錯的大小。但是超過free時malloc會一定出錯麼?也不一定。因為系統的buff和cache在必要 的時候也會優先給malloc使用。只有在不可使用時才會出錯,如被設定為共享記憶體。因此觀察時要綜合這四個位置一起作判斷。當分配記憶體時首先使用free,free不夠的時候從buff和cache中勻得,當還不夠時選擇從swap分割槽中取得。

  1. swap: 交換分割槽的使用情況

    • si : 每秒從硬碟中交換到記憶體中的大小。
    • so :每秒從記憶體中交換到硬碟中的大小。
  2. io : 塊裝置IO統計

    • bi : 每秒從塊裝置讀入記憶體的大小
    • bo : 每秒從記憶體中寫入快裝置的大小

什麼是塊裝置?Linux下的裝置主要分成字元裝置和塊裝置(可以參考LDD《linux device driver》),類似於Socket屬於流裝置,而磁碟一般屬於塊裝置。因此這個引數可以用來衡量寫磁碟的效能。

  1. system : 作業系統中斷和上下文切換統計

    • in : 操作的系統每秒觸發的中斷數目
    • cs : 作業系統每秒上下文切換次數,這裡上下文切換可以認為是系統態到使用者態或者反過來的切換
  2. cpu: cpu相關統計

    • us : 使用者態程式碼執行佔用的cpu時間。
    • sy :系統態程式碼執行佔用的cpu時間。
    • id : cpu空閒時間,也就是執行系統idle的時間,cpu是不可能停機的。
    • wa : 耗費在等待IO上的時間
    • st : 其他的等待時間。

2. vmstat的使用

上面我們裸跑vmstat就可以得到一個輸出,表示的是:自系統最近啟動後虛擬記憶體和CPU的平均情況。

vmstat的呼叫格式為:

vmstat delay count [options]

這裡先介紹一個“-a”選項。 如果使用了 “-a” 選項,我們會發現其輸出和上面描述的有點不一樣。在memory的下面,沒有了buff和cache子列了,取而代之的是inact和active子列。 他們分別表示啟用的和非啟用的記憶體大小。那怎樣理解“啟用”呢?對比增加了-a選和沒有增加-a選項的結果我們可以發現inact + active = cache大小。 也就是我們上面討論,如果系統中free的記憶體不夠了,那麼就去用cache和buff裡面的記憶體。但是並不是都可以用的,其中可以用的就是inact部分。因此 我們可以知道,系統此時還可以使用的記憶體大小為 free+inact大小。如果該和持續下降,那麼我們就要注意了。是不是有記憶體洩露、或者記憶體分配洪請求等 情況的出現了。

除此之外還有個"-d"選項 通過使用“-d”選項,可以僅檢視寫磁碟的效能。有一級表頭 disk, reads, writes, IO四大塊。disk表示的是分割槽名稱。reads和writes分別表示 讀寫扇區數目。其中都有: total merged sectors ms : total : 總共讀取/寫入成功的數目 merged : 合在一起讀取操作的數目 sectors :讀取/寫入成功的扇區數目 ms :一次讀或者寫耗費的時間,單位是毫秒

IO中包含了cur表示當前正在處理的IO數目,s表示每處理一個IO請求耗費的時間,單位是秒。 “-d”選項中包含了很多ram開頭的隨機分割槽。為了更清楚的檢視可以使用 “-p”選項 指定某個分割槽。如 :

vmstat -dp /dev/sda1

可以僅檢視該分割槽硬碟的讀寫情況。

3. 通過vmstat進行診斷

從上面我們瞭解了vmstat的基本使用,就可以拿它當聽診器進行診斷了。執行

vmstat 1 100

會每個一秒輸出一次統計

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     64 180428 394096 30058348    0    0    41   183    3    5  0  0 99  0  0
0  0     64 180428 394096 30058348    0    0     0    44  267  138  0  1 99  0  0
0  0     64 181048 394096 30058348    0    0     0     0  259  223  0  0 100  0  0
0  0     64 181048 394096 30058348    0    0     0     0  254  124  0  0 100  0  0
  1. 情景1:swpd 大小不斷變化,si/so持續變化。 此時說明記憶體頻繁進行換入換出操作,此時系統系能會急劇下降
  2. 情景2:id較高但是free 非常低,如果加上-a引數free+inactiv非常低。 此時記憶體可能被耗盡。
  3. 情景3:wa較高 系統等待IO時間過長,考慮IO的阻塞
  4. 。。。 有待補充