Linux 效能診斷——平均負載 Load 問題
前言
有一回面試,面試官提了一個問題,cpu 使用率不高,但是 Load (平均負載) 很高,你如何查詢問題?
當時我不明白 Load 的意思,面試官解釋說這個指標反映不可中斷狀態的程序比較多。我遂根據過往後端開發經驗,回答可能系統中 io 阻塞比較多,多發於網路 io 問題,用命令netstat -tnp
看看 tcp 連線中 time_wait 狀態多不多...
我知道我的回答很片面,事後複習,做筆記。
什麼是平均負載
熟悉 Linux 者知道,使用top
uptime
命令可以檢視load average
指標。
使用man uptime
檢視 Load average 解釋:
System load averages is the average number of processes that are either in a runnable or uninterruptable state.Aprocessinarunnable stateiseither using the CPU or waiting to use the CPU.A process in uninterruptable state is waiting for some I/O access, eg waiting for disk.The averages are taken over the three time intervals.Load averages are not normalized for the number of CPUs in a system, so aload average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.
理解關鍵地方,平均負載是指,在單位時間內,系統中處於可執行狀態 與不可中斷狀態 的平均程序數,簡稱平均活躍程序數 。值得注意的是,它與 CPU 使用率沒有直接關係
使用命令ps aux
可以檢視程序的狀態 stat,如本文要注意的:
- R 狀態,可執行狀態 ( Running / Runnable ),正在使用 CPU 或者正在等待 CPU 的程序
- D 狀態,不可中斷狀態( Uninterruptitle Sleep, 又稱 Disk Sleep ),正處於核心態關鍵流程中的程序,並且是不可中斷的。
D 狀態為何不可打斷呢,舉個例子,系統呼叫起硬體裝置的 I/O 響應,為了保證資料的一致性,在磁碟裝置返回資料前,它是不能倍其他程序或者中斷打斷的,如果被打斷,就容易造成磁碟資料與程序資料不一致的問題。於是,不可中斷(D)狀態是系統對程序與硬體裝置的一種保護機制。
平均活躍程序數,嚴格意義上,它是活躍程序數的指數衰減平均值(某個量的下降速度和它的值成比例)。通常情況下,理解為單位時間上的活躍程序數 即可。
CPU 利用率與平衡負載
從 CPU 角度來說,Load average 只是反映單位時間內佔用 CPU 的程序數量,而 CPU 利用率與程序數量沒有直接關係,我們可以使用命令top
vmstat
檢視 CPU 的利用率,有以下幾個指標:
- %us:表示使用者空間程式的cpu使用率(沒有通過nice排程)
- %sy:表示系統空間的cpu使用率,主要是核心程式。
- %ni:表示使用者空間且通過nice排程過的程式的cpu使用率。
- %id:空閒cpu
- %wa:cpu執行時在等待io的時間
- %hi:cpu處理硬中斷的數量
- %si:cpu處理軟中斷的數量
- %st:被虛擬機器偷走的cpu
如何衡量合理的平均負載
一般來講,Load average 低於 CPU 數量的話,機器效能滿足服務需求,超出一些也沒關係,Load average 不直接代表 CPU 利用率,可能是 io 阻塞比較多。當 Load average 高於 CPU 數量的 70%,就可能導致程序響應變慢,進而影響服務的正常功能。
從歷史變化量來看
一般來講,top
uptime
提供 load average 三個時間點的指標,分別是:1分鐘、5分鐘、15分鐘。這反映了系統最近的狀態變化趨勢。在實際生產環境中,我們需要做長期的監控記錄。如果有異常的數值變化,比如平均負載數是CPU的兩倍,需要分析調查問題。
從平衡負載與 CPU 利用率 這兩類指標綜合分析
兩類指標的不同,組合出以下幾種可能情況:
- Load average 高,CPU use 高,要麼運行了 CPU 密集型程序(執行緒),要麼有大量等待 CPU 的程序(執行緒)排程
- Load average 高,CPU use 底,運行了 IO 密集型程序
- 兩者都比較低,正常
- Load average 底,CPU use 高,這是不存在的
模擬案例與工具
我們如何分析平衡負載與 CPU 利用率這兩類指標不同組合的案例,尋找造成指標變化的來源?
以下環境為 Linux Arch 4.19 / 4 CPU / 8G Memory
工具列表
-
stress
系統壓力測試工具 -
sysstat
效能分析工具包:-
mpstat
多核 CPU 分析效能工具,mp 的意思是multi processors (多處理器) -
pidstat
程序效能分析工具,pid 意為程序 ID。它用於檢視程序的 CPU、記憶體、I/O以及上下文切換等指標
-
模擬場景
使用 stress 可以模擬以下場景
- CPU密集型程序
# 模擬一個程序, 對 cpu 使用率 100%,限時 600s stress --cpu 1 --timeout 600
- IO 密集型程序
stress 的-i
選項,spawn N workers spinning on sync()
# 模擬一個程序不停的執行 sync stress -i 1 --timeout 600
- 大量程序的場景
# 模擬16個程序, 對 cpu 使用率 100%,限時 600s stress --cpu 16 --timeout 600
工具指標
-
mpstat -P ALL 5
監控所有 CPU,每隔5秒輸出一組資料,注意指標%usr
使用率,%iowait
IO 阻塞時間,從這可以判斷是 CPU 密集型還是 IO 密集型 -
pidstat -u 5 1
統計間隔5秒內,使用過 CPU 的程序的資料,注意指標%usr
使用率,%wait
等待使用 CPU 的時間,從這可以判斷是否程序(執行緒)過多