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. A process in a runnable state is either 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 a load 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 的時間,從這可以判斷是否進程(線程)過多
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章