Linux stress 命令

sparkdev發表於2019-02-08

stress 命令主要用來模擬系統負載較高時的場景,本文介紹其基本用法。文中 demo 的演示環境為 ubuntu 18.04。

基本語法

語法格式:
stress <options>

常用選項:
-c, --cpu N              產生 N 個程式,每個程式都反覆不停的計算隨機數的平方根
-i, --io N                  產生 N 個程式,每個程式反覆呼叫 sync() 將記憶體上的內容寫到硬碟上
-m, --vm N             產生 N 個程式,每個程式不斷分配和釋放記憶體
    --vm-bytes B      指定分配記憶體的大小
    --vm-stride B     不斷的給部分記憶體賦值,讓 COW(Copy On Write)發生
    --vm-hang N      指示每個消耗記憶體的程式在分配到記憶體後轉入睡眠狀態 N 秒,然後釋放記憶體,一直重複執行這個過程
    --vm-keep          一直佔用記憶體,區別於不斷的釋放和重新分配(預設是不斷釋放並重新分配記憶體)
-d, --hadd N           產生 N 個不斷執行 write 和 unlink 函式的程式(建立檔案,寫入內容,刪除檔案)
    --hadd-bytes B  指定檔案大小
-t, --timeout N       在 N 秒後結束程式        
--backoff N            等待N微妙後開始執行
-q, --quiet              程式在執行的過程中不輸出資訊
-n, --dry-run          輸出程式會做什麼而並不實際執行相關的操作
--version                顯示版本號
-v, --verbose          顯示詳細的資訊

安裝 stress

Ubuntu 系統預設沒有安裝 stress,需要通過下面的命令安裝:

$ sudo apt install stress
$ stress --version

消耗 CPU 資源

stress 消耗 CPU 資源的方式是通過呼叫 sqrt 函式計算由 rand 函式產生的隨機數的平方根實現的。下面的命令會產生 4 個這樣的程式不斷的進行計算:

$ stress -c 4

使用 top 命令檢視 CPU 的狀態如下(CPU 在使用者態滿負荷運轉):

消耗記憶體資源

下面的命令產生兩個子程式,每個程式分配 300M 記憶體:

$ stress --vm 2 --vm-bytes 300M --vm-keep

父程式處於睡眠狀態,兩個子程式負責資源消耗。

--vm-keep
一直佔用記憶體,區別於不斷的釋放和重新分配(預設是不斷釋放並重新分配記憶體)。
--vm-hang N
指示每個消耗記憶體的程式在分配到記憶體後轉入睡眠狀態 N 秒,然後釋放記憶體,一直重複執行這個過程。

--vm-keep 和 --vm-hang 都可以用來模擬只有少量記憶體的機器,但是指定它們時 CPU 的使用情況是不一樣的。

$ stress --vm 2 --vm-bytes 500M --vm-keep

一直在進行預設的 stride 操作,user 非常高(cpu 在使用者態忙碌)。

$ stress --vm 2 --vm-bytes 500M --vm-hang 5

上面這兩種狀態不斷切換,但整體上看 CPU 的負載並不高。

--vm-stride B
不斷的給部分記憶體賦值,讓 COW(Copy On Write)發生。只要指定了記憶體相關的選項,這個操作就會執行,只是大小為預設的 4096。賦值記憶體的比例由引數決定:

for (i = 0; i < bytes; i += stride)
    ptr[i] = 'Z';           /* Ensure that COW happens.  */

bytes 為消耗的總記憶體大小,stride 為間隔。
該引數會影響 CPU 狀態 us 和 sy:

$ stress --vm 2 --vm-bytes 500M --vm-stride 64

$ stress --vm 2 --vm-bytes 500M --vm-stride 1M

為什麼會產生這樣的結果?原因是單獨的賦值和對比操作可以讓 CPU 在使用者態的負載佔到 99% 以上。--vm-stride 值增大就意味著減少賦值和對比操作,這樣就增加了記憶體的釋放和分配次數(cpu在核心空間的負載)。
不指定 --vm-stride 選項就使用預設值是 4096,CPU 負載情況居於前兩者之間:

$ stress --vm 2 --vm-bytes 500M

消耗 IO 資源

下面的命令產生 4 個程式,每個程式都反覆呼叫 sync 函式將記憶體上的內容寫到硬碟上:

$ stress -i 4

使用 top 命令檢視 CPU 的狀態如下:

sy 升高,wa(iowait) 非常高。

壓測磁碟及 IO

下面的命令建立一個程式不斷的在磁碟上建立 10M 大小的檔案並寫入內容:

$ stress -d 1 --hdd-bytes 10M

使用 top 命令檢視 CPU 的狀態如下(此時的 CPU 主要消耗在核心態):

下面是 iostat 2 的輸出(同樣是高 iowait,瓶頸是寫磁碟):

其它選項介紹

--verbose
顯示 stress 程式執行過程中的詳細資訊:

--timeout N
在 N 秒後結束程式。

--quiet
stress 程式執行的過程中不輸出資訊。

-n, --dry-run
輸出程式會做什麼而並不實際執行相關的操作:

--backoff N
讓新 fork 出來的程式 sleep N 微秒再開始執行。

除了單獨指定某一類的選項,還可以同時執行多個型別的任務,比如產生 3 個 CPU 程式、3 個 IO 程式、2 個10M 的 vm 程式,並且每個 vm 程式中不迴圈分配釋放記憶體:

$ stress --cpu 3 --io 3 --vm 2 --vm-bytes 10M --vm-keep

總結

對於學習 Linux 效能檢測相關的命令來說,stress 命令是個得力的助手。通過模擬各種高負載情況,可以幫助我們更好的理解系統瓶頸並掌握效能檢測工具的用法。

參考:
stress man page
stress 1.0.4 code

相關文章