如何理解 Linux 中的 load averages
原文:https://mp.weixin.qq.com/s?src=11×tamp=1533697106&ver=1047&signature=poqrJFfcNABv4biKKpa4mZdIW7No2Wo1F5sbZL7ggoVS2GqcSqwQQ8hMulAmezT*zL*klB-eE5BeMyNuyjuIH7YgkBAN25i6*ahhEpWyxqx6vPct-Vr7q7AU0YGe-F*l&new=1
http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages
經(jīng)常和 Linux 打交道的童鞋都知道,load averages 是衡量機(jī)器負(fù)載的關(guān)鍵指標(biāo),但是這個(gè)指標(biāo)是怎樣定義出來(lái)的呢?
和其他系統(tǒng)不同,Linux 上的 load averages 不僅追蹤可運(yùn)行的任務(wù),還追蹤處于不可中斷睡眠狀態(tài)的任務(wù),為什么是這樣呢?這篇文章就來(lái)聊聊這方面的知識(shí)。
Linux 的 load averages 是系統(tǒng)負(fù)載平均值,這個(gè)值將正在運(yùn)行線程(任務(wù))對(duì)于系統(tǒng)的需求,作為處于運(yùn)行和等待狀態(tài)的線程的平均數(shù)量。大多數(shù)工具會(huì)顯示 1 分鐘,5 分鐘和 15 分鐘的平均值:
對(duì)上面的輸出信息稍稍做些解釋
- 如果平均值是 0.0,說(shuō)明系統(tǒng)處于空閑狀態(tài)
- 如果 1 分鐘的平均值大于 5 分鐘或者 15 分鐘,說(shuō)明系統(tǒng)負(fù)載正在增加
- 如果 1 分鐘的平均值小于 5 分鐘或者 15 分鐘,說(shuō)明系統(tǒng)負(fù)載正在減小
- 如果這些值大于 CPU 的核數(shù),說(shuō)明可能遇到了性能問(wèn)題
利用這三個(gè)值,我們可以判斷系統(tǒng)的負(fù)載是在增加還是在減小,這在實(shí)踐中很有用。這三個(gè)中的任意一個(gè)拿出來(lái)也很有用,比如為云服務(wù)的自動(dòng)伸縮設(shè)置閾值。不過(guò),在缺少其他信息的情況下,單看這些值是沒(méi)有意義的。比如 1 分鐘的 load averages 值在 23 到 25 之間,就沒(méi)有任何意義;但如果知道 CPU 核數(shù)并且知道運(yùn)行的任務(wù)是計(jì)算密集型,那這個(gè)值就很有意義。
歷史
最開(kāi)始的時(shí)候,load averages 只顯示對(duì)系統(tǒng) CPU 相關(guān)的需求:運(yùn)行的進(jìn)程數(shù)加上等待的進(jìn)程數(shù)。如 RFC 546 描述的:
TENEX load averages 是衡量 CPU 需求的指標(biāo)。這個(gè)值是給定時(shí)間內(nèi)可運(yùn)行進(jìn)程數(shù)量的平均值。例如,對(duì)于單核 CPU 系統(tǒng),每小時(shí)平均 10 次意思是在該小時(shí)內(nèi)可以期望看到一個(gè)進(jìn)程正在運(yùn)行和另外九個(gè)等待 CPU(即沒(méi)有被 I/O 阻塞) 處于 ready 狀態(tài)的進(jìn)程。
下圖是 1973 年繪制的監(jiān)控圖:
以前操作系統(tǒng)的代碼還可以找到,下面是 TENEX) 定義的一些宏:
NRJAVS==3 ;NUMBER OF LOAD AVERAGES WE MAINTAIN GS RJAV,NRJAVS ;EXPONENTIAL AVERAGES OF NUMBER OF ACTIVE PROCESSES [...] ;UPDATE RUNNABLE JOB AVERAGESDORJAV: MOVEI 2,^D5000MOVEM 2,RJATIM ;SET TIME OF NEXT UPDATEMOVE 4,RJTSUM ;CURRENT INTEGRAL OF NBPROC+NGPROCSUBM 4,RJAVS1 ;DIFFERENCE FROM LAST UPDATEEXCH 4,RJAVS1FSC 4,233 ;FLOAT ITFDVR 4,[5000.0] ;AVERAGE OVER LAST 5000 MS [...] ;TABLE OF EXP(-T/C) FOR T = 5 SEC.EXPFF: EXP 0.920043902 ;C = 1 MINEXP 0.983471344 ;C = 5 MINEXP 0.994459811 ;C = 15 MINLinux 中定義的宏長(zhǎng)下面這樣(代碼出處 include/linux/sched/loadavg.h):
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ #define EXP_5 2014 /* 1/exp(5sec/5min) */ #define EXP_15 2037 /* 1/exp(5sec/15min) */指標(biāo)的三個(gè)粒度
load averages 有 1 分鐘,5 分鐘,15 分鐘三個(gè)粒度的結(jié)果。不過(guò)事實(shí)上,他們并不是真正的平均值,統(tǒng)計(jì)的粒度也不是 1,5,15 分鐘。從上面的代碼中可以看出,1,5 和 15 都是常量,用于計(jì)算指數(shù)衰減的 5 秒平均移動(dòng)和。由此算出的 1 分鐘,5 分鐘和 15 分鐘的 load averages 所反應(yīng)的負(fù)載遠(yuǎn)遠(yuǎn)超過(guò) 1,5,15 分鐘。
假設(shè)在一個(gè)空閑的系統(tǒng)上,開(kāi)啟一個(gè)單線程來(lái)跑 CPU 密集任務(wù),60 秒后 1 分鐘的 load averages 是多少呢?如果 load averages 按普通平均值來(lái)算,這個(gè)值將是 1.0. 下面是一個(gè)繪制成圖的實(shí)驗(yàn)結(jié)果:
在上面的實(shí)驗(yàn)中,所謂的“1 分鐘 load averages”在一分鐘內(nèi)只能達(dá)到 0.62 左右。
Linux 不可中斷任務(wù)
Linux 中剛引入 load averages 時(shí),和其他系統(tǒng)一樣將其作為衡量 CPU 需求的指標(biāo),后來(lái)將其更改為不僅包含可運(yùn)行任務(wù),還包含處于不可中斷狀態(tài)的任務(wù)(TASK_UNINTERRUPTIBLE 或 nr_uninterruptible)。這種狀態(tài)由希望避免信號(hào)中斷的代碼使用,其中包括阻塞在磁盤(pán) I/O 和一些鎖上的任務(wù)。在ps和top的輸出中,這種狀態(tài)被標(biāo)志為“D”。ps(1) 的 man page 將其稱為"不可中斷睡眠狀態(tài)(通常被 IO 阻塞)"
# man ps ..... PROCESS STATE CODESHere are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe thestate of a process:D uninterruptible sleep (usually IO)...為什么 Linux 中的 load averages 要加入不可中斷狀態(tài)呢,而不是像其他系統(tǒng)一樣只計(jì)算 CPU 的需求呢?
加入不可中斷的起源
在 oldlinux.org 找到了一封 1993 年的郵件:
From: Matthias Urlichs <urlichs@smurf.sub.org> Subject: Load average broken ? Date: Fri, 29 Oct 1993 11:37:23 +0200The kernel only counts "runnable" processes when computing the load average. I don't like that; the problem is that processes which are swapping or waiting on "fast", i.e. noninterruptible, I/O, also consume resources.It seems somewhat nonintuitive that the load average goes down when you replace your fast swap disk with a slow swap disk...Anyway, the following patch seems to make the load average much more consistent WRT the subjective speed of the system. And, most important, the load is still zero when nobody is doing anything. ;-)--- kernel/sched.c.orig Fri Oct 29 10:31:11 1993 +++ kernel/sched.c Fri Oct 29 10:32:51 1993 @@ -414,7 +414,9 @@unsigned long nr = 0;for(p = &LAST_TASK; p > &FIRST_TASK; --p) - if (*p && (*p)->state == TASK_RUNNING) + if (*p && ((*p)->state == TASK_RUNNING) || + (*p)->state == TASK_UNINTERRUPTIBLE) || + (*p)->state == TASK_SWAPPING))nr += FIXED_1;return nr;} -- Matthias Urlichs \ XLink-POP N|rnberg | EMail: urlichs@smurf.sub.org Schleiermacherstra_e 12 \ Unix+Linux+Mac | Phone: ...please use email. 90491 N|rnberg (Germany) \ Consulting+Networking+Programming+etc'ing 42看到這么久之前的想法還是很令人驚嘆的。
這也證明了 Linux 改變 load averages 的含義,使其不僅體現(xiàn)對(duì) CPU 的需要,是有意的,這讓 load averages 從“CPU 負(fù)載均衡”變成了“系統(tǒng)負(fù)載均衡”。
郵件中舉交換磁盤(pán)速度慢的例子是有道理的:通過(guò)降低系統(tǒng)性能,系統(tǒng)需求(運(yùn)行和排隊(duì)的進(jìn)程數(shù))應(yīng)該增加;但是如果僅僅根據(jù) CPU 運(yùn)行狀態(tài),那么 load averages 值應(yīng)該會(huì)下降。Matthias 認(rèn)為這是不直觀的,所以修改了代碼。
現(xiàn)代系統(tǒng)的不可中斷
但是難道不會(huì)出現(xiàn)磁盤(pán) I/O 不能解釋 Linux load averages 過(guò)高的情況嗎?這種情況是會(huì)出現(xiàn)的,這是因?yàn)樵诂F(xiàn)代 Linux(4.12)版本中,有將近 400 處代碼設(shè)置了TASK_UNINTERRUPTIBLE狀態(tài),包括一些鎖原語(yǔ)中。其中部分代碼可能不需要統(tǒng)計(jì)在 load averages 中。
既然TASK_UNINTERRUPTIBLE在更多的地方被用到,那么是否應(yīng)該將 load averages 改成只統(tǒng)計(jì) CPU 和磁盤(pán)需求呢?Linux 調(diào)度程序的維護(hù)者 Peter Zijstra 有一個(gè)想法:將TASK_UNINTERRUPTIBLE替換成task_struct->in_iowait,這樣 load averages 就更貼近磁盤(pán) I/O 的需求。這樣又引入了另外一個(gè)問(wèn)題,我們到底想要從 load averages 中得到什么?我們是需要用線程對(duì)系統(tǒng)的需求來(lái)衡量負(fù)載,還是只通過(guò)物理資源的使用情況來(lái)衡量負(fù)載呢?如果是前者的話,那么應(yīng)該包含等待不間斷鎖的線程,因?yàn)檫@些線程并沒(méi)有閑置。所以也許 Linux 的 load averages 已經(jīng)按我們需要的方式工作了。
理解 Linux 的 load averages
也許真正的問(wèn)題在于“l(fā)oad averages”這個(gè)詞和“I/O”一樣含糊不清。到底是哪種 I/O 呢?是磁盤(pán) I/O?文件系統(tǒng) I/O?還是網(wǎng)絡(luò) I/O。類似的,到底是哪種 load averages 呢?是 CPU 平均負(fù)載?還是系統(tǒng)平均負(fù)載?下面做一個(gè)總結(jié)吧:
- 在 Linux 上,load averages 的真實(shí)含義是“系統(tǒng)平均負(fù)載”,即對(duì)整個(gè)系統(tǒng),測(cè)量正在工作并等待工作的線程數(shù)(CPU,磁盤(pán),不可中斷鎖)。換句話說(shuō),這種方式測(cè)量的是不完全空閑的線程數(shù)量。這種方式的優(yōu)勢(shì)在于包括了對(duì)不同資源的需求。
- 在其他的系統(tǒng)上,load averages 的含義是“CPU 平均負(fù)載”,這組值用于測(cè)量正在占有 CPU 執(zhí)行權(quán)的線程數(shù)量加上等待 CPU 的線程數(shù)量。
還有另一種可能的類型:“物理資源負(fù)載平均值”,其中包括僅用于物理資源(CPU+ 磁盤(pán))的負(fù)載。
更精確的測(cè)量數(shù)據(jù)
當(dāng) Linux 的 load averages 值增加時(shí),可以判斷任務(wù)對(duì)系統(tǒng)資源(CPU,磁盤(pán)和鎖)有了更高的需求,但是到底是對(duì)哪種資源的需求增長(zhǎng)了呢?這時(shí)可以用其他的指標(biāo)來(lái)進(jìn)行判斷。比如,CPU 資源有如下指標(biāo):
- 單個(gè) CPU 使用率:可以用命令mpstat -P ALL 1查看
- 每個(gè)進(jìn)程的 CPU 使用率:可用命令top,pidstat 1查看
- 每個(gè)線程運(yùn)行隊(duì)列(調(diào)度程序)延遲:可用命令perf sched查看,也可以查看文件/proc/PID/schedstats
- CPU 運(yùn)行隊(duì)列延遲:可用命令perf sched查看,也可以查看文件/proc/schedstat
- CPU 運(yùn)行隊(duì)列長(zhǎng)度:可用vmstat 1命令查看。
上面提供的指標(biāo)中,前兩個(gè)用來(lái)衡量使用率,后三個(gè)用來(lái)度量系統(tǒng)飽和度。利用率指標(biāo)對(duì)于衡量工作負(fù)載很有用,而飽和度指標(biāo)可用來(lái)識(shí)別性能問(wèn)題。衡量 CPU 飽和度的最佳指標(biāo)是運(yùn)行隊(duì)列(或調(diào)度程序)的延遲,延遲是指任務(wù)或者線程處于可運(yùn)行狀態(tài),但必須等待 CPU 的時(shí)間。通過(guò)這樣的指標(biāo)可以用來(lái)衡量性能問(wèn)題的嚴(yán)重程度,比如線程等待調(diào)度的時(shí)間在運(yùn)行時(shí)間中占的百分比。通過(guò)觀察運(yùn)行隊(duì)列長(zhǎng)度可以很方便判斷是否存在問(wèn)題,但比較難定位到問(wèn)題產(chǎn)生的原因。
schedstats功能在 Linux 4.6 中成為內(nèi)核可調(diào)參數(shù)(sysctl.kernel.sched_schedstats),默認(rèn)是關(guān)閉的。
盡管有更明確的指標(biāo),但并不意味著 load averages 是無(wú)用的。這組指標(biāo)已經(jīng)成功用于云計(jì)算微服務(wù)的擴(kuò)展策略,微服務(wù)根據(jù)不同的負(fù)載值做出反應(yīng)。有了這些判斷的依據(jù),即使在自動(dòng)擴(kuò)容時(shí)犯錯(cuò)也保險(xiǎn)多了:擴(kuò)容實(shí)例會(huì)花更多的錢(qián),不擴(kuò)容則會(huì)損失用戶。如果擴(kuò)容太多,后來(lái)調(diào)查一下糾正就是了。
總結(jié)
在 1993 年,一位 Linux 工程師發(fā)現(xiàn)了一個(gè)非直觀的 load averages 情況,于是提交了三行代碼的補(bǔ)丁將 load averages 的含義由“CPU 負(fù)載平均值”變成了“系統(tǒng)負(fù)載平均值”。這次的變動(dòng)在統(tǒng)計(jì)中包括了不可中斷狀態(tài)下的任務(wù),所以 load averages 值不僅反映了對(duì) CPU 的需求,還反映了對(duì)磁盤(pán)資源的需求。系統(tǒng)平均負(fù)載計(jì)算正在工作和等待工作的線程的數(shù)量,并且統(tǒng)計(jì) 1 分鐘,5 分鐘,15 分鐘指數(shù)衰減的移動(dòng)總和平均值。通過(guò)這三個(gè)值,能夠知道系統(tǒng)的負(fù)載是在增加還是在減小。
Linux 中對(duì)不可中斷狀態(tài)的使用越來(lái)越多,現(xiàn)在已經(jīng)包括了不可中斷的鎖原語(yǔ)。如果需要衡量處于運(yùn)行狀態(tài)和等待狀態(tài)的線程對(duì)于系統(tǒng)的需求,那么 load averages 依然是很好的指標(biāo)。
最后引用 kernel/sched/loadavg.c 頭部的注釋來(lái)結(jié)束吧。
- This file contains the magic bits required to compute the global loadavg
- figure. Its a silly number but people think its important. We go through
- great pains to make it work on big machines and tickless kernels.
轉(zhuǎn)載于:https://www.cnblogs.com/Irving/p/9441553.html
總結(jié)
以上是生活随笔為你收集整理的如何理解 Linux 中的 load averages的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 国产山寨Switch现身 支持4K输出:
- 下一篇: linux命令目录