日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

深度好文:全面解析 Linux Load

 

1 linux load 準(zhǔn)確含義

日常運(yùn)維中我們經(jīng)常會(huì)遇到linux系統(tǒng)load過(guò)高的問(wèn)題,但是圍繞linux load是如何計(jì)算的問(wèn)題,業(yè)界還沒(méi)有系統(tǒng)的論述文章。本文將全面系統(tǒng)闡述linux load計(jì)算原理和排查影響因素的方法。

日常獲取linux load的方法無(wú)外乎通過(guò)top、w、uptime等linux系統(tǒng)命令進(jìn)行獲取。事實(shí)上這些linux系統(tǒng)命令打印的load值都是通過(guò)/proc/loadavg中獲取的,大家可以在自己的linux中運(yùn)行如下命令:

深度好文:全面解析 Linux Load

在這里我們可以看到系統(tǒng)命令top、w、uptime都在procps-ng rpm包中,老一點(diǎn)版本linux中包名叫procps。有興趣的同學(xué)可以下載procps-ng源碼包,看看load值是否取自/proc/loadavg。

/proc/目錄中mount的是一種叫proc的linux偽文件系統(tǒng),主要被用作內(nèi)核數(shù)據(jù)結(jié)構(gòu)的接口。我們可以通過(guò)如下方法查看其中的偽文件和數(shù)值的含義。

深度好文:全面解析 Linux Load

這段話大意是說(shuō),loadavg 文件中前三個(gè)字段是平均負(fù)載值,分別代表1、5 和 15 分鐘的作業(yè)(job)數(shù)量的平均值,作業(yè)(job)包括運(yùn)行隊(duì)列(state R)或者等待磁盤(pán)I/O(state D)兩種類(lèi)型。這里面有3層信息:

  1. /proc/loadavg中前三個(gè)數(shù)字分別表示load1、load5、load15的值。

  2. load值代表的是對(duì)應(yīng)時(shí)間內(nèi)的jobs的平均數(shù)量,比如load1就表示過(guò)去1分鐘內(nèi)的jobs數(shù)量的平均值。job主要是一個(gè)shell概念,和進(jìn)程組概念近似,這里應(yīng)該屬于用詞不當(dāng)(后面會(huì)分析,準(zhǔn)確的用詞應(yīng)該是內(nèi)核中的tasks或用戶(hù)空間中的threads概念)。

  3. 而且只包含state狀態(tài)為R和D的兩種jobs,其他state狀態(tài)不包含在內(nèi)。

 

2 分解 Linux load 的腳本工具 load2process

很顯然具體的load1、load5和load15的值是內(nèi)核計(jì)算之后,通過(guò)proc文件系統(tǒng)提供給用戶(hù)空間的。要深入到內(nèi)核中查看load的相關(guān)代碼搞懂load計(jì)算過(guò)程,也非易事。而真正有個(gè)別能看懂內(nèi)核代碼的人分析一下load計(jì)算過(guò)程的相關(guān)代碼,廣大讀者看完之后也還是無(wú)從下手。

在這里我們先拋開(kāi)復(fù)雜的內(nèi)核代碼,直接給大家上干貨load2process工具腳本,初步了解分解linux load的方法。具體獲取方法如下:

深度好文:全面解析 Linux Load

load2process中的關(guān)鍵腳本工具是load2process和load2pid,主要內(nèi)容如下:

深度好文:全面解析 Linux Load

簡(jiǎn)單解釋一下這幾個(gè)ps命令的參數(shù):

  • -e參數(shù),顯示當(dāng)前系統(tǒng)中所有進(jìn)程;

  • -L參數(shù),對(duì)每一個(gè)進(jìn)程信息都展開(kāi)顯示包含的所有線程,每個(gè)線程展開(kāi)一行;

  • h參數(shù),隱藏ps命令的第一行header標(biāo)題信息;

  • o state,ucmd,這里o和state,ucmd是組合在一起生效的,只輸出state和ucmd這兩列信息,state表示線程狀態(tài),ucmd表示線程名稱(chēng)。

  • o state,pid,cmd,這里o和state,pid,cmd是組合在一起生效的,只輸出state,pid和cmd三列信息,pid表示進(jìn)程id,cmd表示完整的線程名稱(chēng)。

找一臺(tái)比較繁忙的機(jī)器,運(yùn)行下以上腳本,同時(shí)獲取當(dāng)時(shí)的load情況。

深度好文:全面解析 Linux Load

load2process 輸出結(jié)果中第一列各數(shù)字相加為31,基本上和load1值26.92差不多,具體存在的差異后面會(huì)分析。此時(shí)如果想將load1值拆解到具體的線程級(jí)別,即可通過(guò)這個(gè)輸出結(jié)果看到R狀態(tài)的tasker_1是影響load1值的主要因素,且數(shù)量上貢獻(xiàn)了18個(gè)。

load2process除以上這個(gè)用法外,還有如下幾種用法。

深度好文:全面解析 Linux Load

如果在執(zhí)行 ./load2process 后,結(jié)果中的第三列比較集中于JAVA、Python和php等進(jìn)程名。則可以繼續(xù)使用load2pid工具進(jìn)行進(jìn)一步load分解。效果如下:

深度好文:全面解析 Linux Load

 

3 更靈敏的load5s和load值預(yù)測(cè)

寫(xiě)到這里,很多同學(xué)可能還是會(huì)有些懷疑,分解linux load就這么簡(jiǎn)單嗎?下面會(huì)通過(guò)引入load5s的概念,將內(nèi)核中復(fù)雜的load算法盡量轉(zhuǎn)換到用戶(hù)空間,讓讀者以一個(gè)看得見(jiàn)摸得著的方式來(lái)體會(huì)load的計(jì)算過(guò)程。

平時(shí)分析load高時(shí),很多資料上都會(huì)說(shuō)看load1、load5和load15的趨勢(shì)。如果load15很高,但是load1已經(jīng)比較低了,那說(shuō)明系統(tǒng)已經(jīng)處于逐步恢復(fù)中。反之,如果load1很高、load15比較低,那說(shuō)明系統(tǒng)正在越來(lái)越嚴(yán)重。這都說(shuō)的沒(méi)錯(cuò),也很容易理解,load1比load15更加靈敏。那有沒(méi)有比load1更加靈敏的load值呢?

加載load5s的內(nèi)核模塊,即可獲取更加靈敏的5秒鐘load average(目前已經(jīng)適配過(guò)centos7的3.10.0內(nèi)核和centos6的2.6.32內(nèi)核)。具體如下:

深度好文:全面解析 Linux Load

安裝完load5s.ko內(nèi)核模塊之后,即可在/proc/目錄中獲取load5s值:

多次cat這個(gè)偽文件可以發(fā)現(xiàn),該值5秒內(nèi)不會(huì)變化,每隔5秒會(huì)發(fā)生變化。這就是比load1更加靈敏的load5s值。也就是說(shuō),如果你安裝了load5s模塊,當(dāng)你的load1高時(shí),你可以看看load5s的值,如果它已經(jīng)不高了,很可能說(shuō)明你的系統(tǒng)已經(jīng)開(kāi)始逐步恢復(fù)中。

load5s除了比load1更加靈敏這個(gè)用途之外,它也是能幫我們揭示load1、load5和load15的計(jì)算邏輯的最關(guān)鍵因素。我們可以嘗試在安裝了load5s模塊的機(jī)器上,運(yùn)行如下load_predict.sh的shell腳本。

(下圖為節(jié)選,詳情可參考GIT)

深度好文:全面解析 Linux Load

運(yùn)行shell腳本后有如下輸出:

深度好文:全面解析 Linux Load

從數(shù)據(jù)結(jié)果中我們可以看到,current_load列和predict_load列分別在load1、load5和load15三種情況下驚人的一致。其中current_load列是從當(dāng)前系統(tǒng)中采集出來(lái)的load值,而predict_load是我們通過(guò)shell腳本中運(yùn)算預(yù)測(cè)的load1、load5和load15的值,大家不妨多運(yùn)行幾次load_predict.sh腳本進(jìn)行驗(yàn)證(采集值和預(yù)測(cè)值最多只有0.01的誤差)。

此時(shí),我們?cè)倩剡^(guò)頭來(lái)仔細(xì)看這個(gè)load_predict.sh腳本,原來(lái)這就是linux load的計(jì)算過(guò)程。

 

4 Linux內(nèi)核中l(wèi)oad相關(guān)代碼分析

了解了linux load的計(jì)算邏輯,我們?cè)賮?lái)對(duì)照一下內(nèi)核代碼,以?xún)?nèi)核3.10.0版本為例。將shell代碼和c代碼對(duì)比著看看,相信大家很快就會(huì)理解內(nèi)核中l(wèi)oad相關(guān)的C語(yǔ)言代碼。

首先來(lái)看下/proc/loadavg偽文件對(duì)應(yīng)的內(nèi)核代碼。

深度好文:全面解析 Linux Load

LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0])預(yù)編譯之后是((avnrun[0]) >> 11), ((((avnrun[0]) & ((1<<11)-1)) * 100) >> 11)。由于內(nèi)核沒(méi)有小數(shù)計(jì)算,這段代碼本質(zhì)上是實(shí)現(xiàn)了avnrun[0]除以2048且取2位小數(shù)的浮點(diǎn)運(yùn)算。

get_avenrun函數(shù)定義在kernel/sched/core.c頁(yè)面。(下圖為節(jié)選,詳情可參考GIT)

深度好文:全面解析 Linux Load

我們可以看到get_avenrun函數(shù)通過(guò)avenrun全局?jǐn)?shù)組變量,返回上面的avnrun數(shù)組變量。avenrun全局?jǐn)?shù)組變量在calc_global_load函數(shù)中每隔5001毫秒,由calc_load函數(shù)將active值添加到原有的load值中,進(jìn)而產(chǎn)生新的load值。

其中l(wèi)oad1、load5和load15的區(qū)別只是第二個(gè)exp參數(shù)傳入給calc_load函數(shù)不同的值,依次為1884、2014和2037。這里active值從calc_load_tasks全局結(jié)構(gòu)體變量獲取。calc_load_tasks全局結(jié)構(gòu)體變量在calc_load_account_active函數(shù)中設(shè)置,而整個(gè)值的最初來(lái)源是calc_load_fold_active函數(shù)。

在函數(shù)calc_load_fold_active中,我們可以看到最終獲取的是rq(run queue)隊(duì)列中的this_rq->nr_running和this_rq->nr_uninterruptible兩種狀態(tài)的task數(shù)。

熟悉cpu調(diào)度算法的同學(xué)知道,這里實(shí)際上是把每個(gè)cpu隊(duì)列里的nr_running和nr_uninterruptible值都匯總到一起。而nr_running和nr_uninterruptible正好對(duì)應(yīng)于用戶(hù)空間中的R和D兩種狀態(tài)的線程的數(shù)量。

回頭再看前面man page說(shuō)明中的jobs概念顯然是不對(duì)的,正確的應(yīng)該是tasks概念(用戶(hù)空間對(duì)應(yīng)threads概念)。

load2process輸出結(jié)果中第一列之和、load5s和load1值之間的關(guān)系也一目了然。load2process第一列之和是運(yùn)行這個(gè)腳本的瞬時(shí)nr_running和nr_uninterruptible狀態(tài)線程數(shù)之和。load5s值是每5001毫秒對(duì)nr_running和nr_uninterruptible狀態(tài)線程數(shù)之和的一個(gè)采樣。load1是對(duì)之前歷史所有l(wèi)oad5s采樣值按某種算法的平均值。

 

5 內(nèi)核代碼的反匯編

搞懂了內(nèi)核load相關(guān)代碼之后,我們還是要回過(guò)頭來(lái)再看看load5s的實(shí)現(xiàn)機(jī)制。理解了load5s的實(shí)現(xiàn),才能讓我們更加相信腳本load_predict.sh中的load計(jì)算邏輯。

而在此之前有必要先搞清楚內(nèi)核反匯編的知識(shí)。linux啟動(dòng)時(shí)加載的內(nèi)核binary程序存儲(chǔ)在/boot/目錄中,名稱(chēng)以vmlinuz開(kāi)頭,再加版本號(hào)命名。

深度好文:全面解析 Linux Load

可以看到vmlinux是bzImage自解壓格式。這種格式是無(wú)法直接進(jìn)行反匯編的,首先需要進(jìn)行解壓縮。bizip壓縮包內(nèi)容的開(kāi)始頭部可以通過(guò)“1f 8b 08”這個(gè)簽名來(lái)查找。

深度好文:全面解析 Linux Load

返回decompression OK表示解壓縮成功。下一步對(duì)其進(jìn)行反匯編。objdump有-d和-D兩個(gè)選項(xiàng),這里選擇-d即可。-M att表示按AT&T匯編語(yǔ)法進(jìn)行反匯編。

深度好文:全面解析 Linux Load

打開(kāi)匯編文件vmlinuzu_d.dis,我們發(fā)現(xiàn)這里面缺少一些符號(hào)信息,原來(lái)vmlinuz在在內(nèi)核編譯時(shí),去掉了debug信息。

同時(shí)我們也了解到linux也提供了kernel-debug包,在其中包含了符號(hào)信息。從centos官方網(wǎng)址下載和安裝相關(guān)包,http://debuginfo.centos.org/7/x86_64/。

深度好文:全面解析 Linux Load

復(fù)制出帶符號(hào)的vmlinux文件。不方便安裝的情況下,也可以使用rpm包直接解壓文件的方式。

深度好文:全面解析 Linux Load

下面我們也對(duì)vmlinux進(jìn)行反匯編。

深度好文:全面解析 Linux Load

對(duì)比vmlinux_d.dis和vmlinuzu_d.dis這兩個(gè)文件中的匯編代碼,我們可以發(fā)現(xiàn)vmlinux_d.dis除了比vmlinuzu_d.dis多了更豐富的符號(hào)信息之外,其他內(nèi)容高度一致。有了這樣的結(jié)論,我們就可以放心的使用vmlinux_d.dis匯編代碼來(lái)分析我們的load5s了。

 

6 Load5s 的 Kprobe 實(shí)現(xiàn)原理

Load5s主要使用了kprobe內(nèi)核探針技術(shù)。kprobe是linux內(nèi)核的一個(gè)重要特性,它可以能夠在不修改現(xiàn)有代碼的基礎(chǔ)上,靈活的hook內(nèi)核代碼的執(zhí)行。其中這樣兩個(gè)關(guān)鍵屬性symbol_name和offset可以確定在內(nèi)核的任意一個(gè)函數(shù)中的某一個(gè)偏移地址處進(jìn)行hook。

首先,根據(jù)前面對(duì)代碼的分析可以,我們關(guān)心的變量是calc_global_load函數(shù)中calc_load_tasks全局結(jié)構(gòu)體變量的counter屬性值。這個(gè)全局變量calc_load_tasks正是當(dāng)時(shí)內(nèi)核中nr_running和nr_uninterruptible兩種狀態(tài)的tasks數(shù)之和。

確定函數(shù)和函數(shù)內(nèi)部的偏移量之后,我們可以通過(guò)kallsyms_lookup_name函數(shù)獲取全局變量的calc_load_tasks內(nèi)存地址,進(jìn)而獲取calc_load_tasks全局變量的值。

確定恰當(dāng)?shù)暮瘮?shù)內(nèi)偏移地址,需要你對(duì)匯編語(yǔ)言比較精通。3.10.0和2.6.32內(nèi)核已經(jīng)確定,其他版本內(nèi)核可以按如下方法嘗試獲得。

深度好文:全面解析 Linux Load

對(duì)照c代碼,源代碼中有對(duì)calc_load_tasks全局變量進(jìn)行修改的操作,因此,我們?nèi)ock add %rdx,0xdd15d9(%rip)這行匯編指令之后的內(nèi)存地址取偏移量比較穩(wěn)妥。

深度好文:全面解析 Linux Load

當(dāng)分別取ffffffff810c2a4e和ffffffff810c2a4f處的偏移地址時(shí),register_kprobe(&kp)會(huì)執(zhí)行注冊(cè)出錯(cuò)。主要是這個(gè)注冊(cè)函數(shù)中的check_kprobe_address_safe(p, &probed_mod) 會(huì)對(duì)偏移地址進(jìn)行合法性檢查。這個(gè)地址檢查函數(shù)具體實(shí)現(xiàn)原理此處不做過(guò)多闡述。

我們順序再次嘗試ffffffff810c2a56地址時(shí)結(jié)果正常,此時(shí)函數(shù)內(nèi)偏移量是0x23d,使用ffffffff810c2a56減去函數(shù)的開(kāi)始地址ffffffff810c2820獲得。

最后,我們的load5s代碼如下:(下圖為節(jié)選,詳情可參考GIT)

深度好文:全面解析 Linux Load

將以上代碼進(jìn)行編譯,即可獲得load5s.ko內(nèi)核模塊。如上述小結(jié)三中的make步驟。

 

7 Linux load 中的數(shù)學(xué)問(wèn)題

接下來(lái)再對(duì)load計(jì)算過(guò)程中的數(shù)學(xué)問(wèn)題做一些分析。在前面kernel源碼分析部分,我們可以在預(yù)編譯之后的core.i文件中看到calc_global_load調(diào)用calc_load函數(shù)時(shí),針對(duì)load1、load5和load15,給calc_load的第二個(gè)參數(shù)分別傳入了三個(gè)不同的參數(shù)值1884,2014和2037。那么這3個(gè)值是怎么得來(lái)的呢?查看內(nèi)核源碼之后,我們可以發(fā)現(xiàn)有這樣的計(jì)算公式。

深度好文:全面解析 Linux Load

分別將x代入60秒(1分鐘)、300秒(5分鐘)和900秒(15分鐘)可以得到如下結(jié)果

深度好文:全面解析 Linux Load

這里面exp函數(shù)是求e的n次方的函數(shù),e是自然對(duì)數(shù)2.71828….。明確了這個(gè)公式,我們?cè)趤?lái)看load的遞歸調(diào)用過(guò)程。假設(shè)每5s的load5s的采樣值依次是active1 active2 active3 active4 …….,x是計(jì)算跨度,比如load1是60/5,load5是300/5。那么我們可以將任意時(shí)刻的load值的計(jì)算過(guò)程轉(zhuǎn)換為:

深度好文:全面解析 Linux Load

其中的各個(gè)權(quán)重之和是:

深度好文:全面解析 Linux Load

小學(xué)生奧數(shù)題,無(wú)窮數(shù)列,和正好等于1。

采用這樣的計(jì)算方法,遞歸出來(lái)的load值是否更能代表系統(tǒng)的平均運(yùn)行狀況呢?由遠(yuǎn)及近權(quán)重越來(lái)越大。

到此我們已經(jīng)對(duì)Linux load的計(jì)量有了一個(gè)比較完整的認(rèn)識(shí)。有了以上的分析,接下去我們將聚焦于Linux load的系統(tǒng)性的監(jiān)控。

 

8 Linux load 中的監(jiān)控

Load5s的值可以清晰的揭示linux load1 load5 load15的計(jì)算邏輯,但是load5s畢竟依賴(lài)內(nèi)核模塊的支持,對(duì)日常運(yùn)維來(lái)說(shuō)還是比較厚重。這里有一個(gè)比較輕量級(jí)的替代方案。

前文提到load2process輸出結(jié)果中第一列各數(shù)字相加的事情,load2process中還封裝了一個(gè)-s參數(shù)(summary)。

深度好文:全面解析 Linux Load

輸出結(jié)果23表示當(dāng)前l(fā)oad2process運(yùn)行的同時(shí),linux系統(tǒng)上所有R和D狀態(tài)線程數(shù)之和。與load5s不同之處是,load5s是內(nèi)核中每隔5001毫秒進(jìn)行一次快照,而load2process -s是更加實(shí)時(shí)的數(shù)據(jù)。

當(dāng)系統(tǒng)load高時(shí),我們可以登錄機(jī)器使用load2process和load2pid進(jìn)行原因定位。有時(shí)候系統(tǒng)load高發(fā)生在半夜,或者發(fā)生在白天但并不在電腦前。這個(gè)時(shí)候,就需要依靠監(jiān)控系統(tǒng)協(xié)助我們進(jìn)行采集。在我們的load2process包中也提供了一個(gè)用于分解load的監(jiān)控采集腳本check_load_process,具體使用方法如下。

深度好文:全面解析 Linux Load

先介紹下這個(gè)監(jiān)控采集腳本的使用。有2個(gè)參數(shù)load_threshold和thread_threshold,可以省略,默認(rèn)值分別是2和0.4。返回值是一個(gè)json格式的,方便于一些高級(jí)語(yǔ)言解析。下面分別介紹這2個(gè)參數(shù)的含義。

首先必須先說(shuō)一下如何判斷l(xiāng)inux load高不高,單純的看一個(gè)load1的絕對(duì)值是沒(méi)有任何意義的。同樣是load1值64,分別對(duì)于32核機(jī)器、64核機(jī)器和96核機(jī)器的壓力是完全不同的。所以第一個(gè)參數(shù)load_threshold的閾值2,適用于判斷當(dāng)前監(jiān)控采集腳本執(zhí)行時(shí)機(jī)器的load是否高。根據(jù)我們的日常經(jīng)驗(yàn),當(dāng)前壓力大于機(jī)器的核數(shù)的200%時(shí),可以用于判斷機(jī)器負(fù)載較高。當(dāng)然,對(duì)于一些靈敏度特別高的重要機(jī)器角色,你完全可以將此閾值調(diào)整為0.7。

第二個(gè)參數(shù)thread_threshold比較好理解。當(dāng)我們判斷系統(tǒng)load較高時(shí),系統(tǒng)上除了有幾個(gè)導(dǎo)致系統(tǒng)load高的進(jìn)程(線程)之外,還有一些很本分的常規(guī)進(jìn)程(線程)。我們通過(guò)thread_threshold參數(shù)將他們過(guò)濾掉,即只保留壓力達(dá)到機(jī)器核數(shù)40%以上的進(jìn)程(線程)。

上面這個(gè)check_load_process監(jiān)控采集指令是根據(jù)load2process腳本改造的。如果機(jī)器角色上是java、python或php等進(jìn)程密集,那么需要根據(jù)load2pid腳本再改造一個(gè)監(jiān)控采集指令。

 

9 R&D 狀態(tài)對(duì) Linux load 的不同影響

很多公司在對(duì)load高進(jìn)行監(jiān)控的時(shí)候,會(huì)對(duì)load進(jìn)行總體監(jiān)控,并不區(qū)分其中的R和D兩種類(lèi)型的具體構(gòu)成。事實(shí)上同樣數(shù)量的R或D對(duì)系統(tǒng)的影響是遠(yuǎn)遠(yuǎn)不同的:

  • 一般來(lái)說(shuō)如果是R狀態(tài)為主導(dǎo)致的load高,系統(tǒng)就會(huì)特別卡。更準(zhǔn)確的來(lái)說(shuō),R狀態(tài)的多少,主要還是要和CPU核數(shù)相關(guān),大于主機(jī)CPU核數(shù)2倍以上,系統(tǒng)就會(huì)出現(xiàn)嚴(yán)重問(wèn)題,出現(xiàn)多個(gè)R狀態(tài)線程爭(zhēng)搶CPU資源的情況。

  • 如果是D狀態(tài)為主導(dǎo)致的load高,曾經(jīng)就有案例,當(dāng)時(shí)的系統(tǒng)load高達(dá)11000多,但是整個(gè)操作系統(tǒng)還能正常服務(wù)。

既然這樣,那我們就還需要進(jìn)一步將load15、load5和load1,甚至load5s中的R和D狀態(tài)分別進(jìn)行監(jiān)控記錄,以便我們更加準(zhǔn)確的判斷系統(tǒng)健康程度。非常幸運(yùn)的是kernel提供了這樣的數(shù)據(jù)。

深度好文:全面解析 Linux Load

在/proc/loadavg偽文件中,內(nèi)核還提供了一個(gè)nr_running(斜線前38)的值。這個(gè)值表示當(dāng)前系統(tǒng)中正在進(jìn)行中的R狀態(tài)的線程數(shù)。linux的sar命令也對(duì)這個(gè)nr_running值進(jìn)行了持久化的采集,即如下輸出結(jié)果中的runq-sz列。

深度好文:全面解析 Linux Load

從上面這個(gè)案例中,也可以看到盡管load已經(jīng)高達(dá)200多,但是runq-sz(即nr_running)值只有不到10。充分說(shuō)明導(dǎo)致load高的原因主要是當(dāng)時(shí)D狀態(tài)線程數(shù)過(guò)高。

區(qū)分了R和D狀態(tài)線程對(duì)Linux load的影響,我們?cè)賮?lái)看一個(gè)絕大多數(shù)人都曾經(jīng)歷的誤區(qū)。當(dāng)linux系統(tǒng)load標(biāo)高時(shí),很多人都會(huì)去top一下,查看當(dāng)前系統(tǒng)誰(shuí)占用的CPU Usage最高。這種排查方法忽略了一下2個(gè)事實(shí),很多時(shí)候可能不能得到滿意的答案。

只有當(dāng)進(jìn)程(線程)處于R狀態(tài)時(shí),才耗費(fèi)CPU Usage,其他狀態(tài)(包括D狀態(tài))并不耗費(fèi)CPU Usage。當(dāng)load高主要是由D狀態(tài)線程數(shù)量過(guò)多導(dǎo)致的時(shí)候,此時(shí)從top中按CPU Usage的排名是不會(huì)發(fā)現(xiàn)任何線索的。

即使當(dāng)load高是由R狀態(tài)線程數(shù)量過(guò)多導(dǎo)致,如果運(yùn)行top命令時(shí)導(dǎo)致load高的R狀態(tài)線程已經(jīng)結(jié)束,此時(shí)也不會(huì)從按CPU Usage的排名的top輸出中發(fā)現(xiàn)線索的。默認(rèn)情況下,top命令是3秒中刷新,只顯示3秒內(nèi)的CPU Usage信息。

 

10 分析 Linux 系統(tǒng) load 高的問(wèn)題

既然影響load的線程狀態(tài)有R和D兩種,那么再結(jié)合load在不同程序線程之間的聚合情況,我們將系統(tǒng)load高時(shí),劃分為如下四種場(chǎng)景:

  1. 由單個(gè)程序線程R狀態(tài)高導(dǎo)致。

    比如load1是200,load2process結(jié)果顯示“160 R process1”,那么此時(shí)可以判斷導(dǎo)致load高的主要原因是process1。

    如果是我們業(yè)務(wù)自己開(kāi)發(fā)的程序,那么很多時(shí)候是由于程序員沒(méi)有注意并發(fā)數(shù)限制、執(zhí)行了一些耗費(fèi)CPU資源的任務(wù)。

    也有可能是陷入了自旋鎖的陷阱。

  2. 由多個(gè)程序線程R狀態(tài)高導(dǎo)致。

    比如load1是200,load2process結(jié)果顯示“20 R process1,15 R process2,14 R process3,10 R process4…….”,這種情況在日常運(yùn)維中不常見(jiàn)。

  3. 由單個(gè)程序線程D狀態(tài)高導(dǎo)致。

    比如load1是1000,load2process結(jié)果顯示“950 D process1”。

    此時(shí)可以查看這個(gè)程序?qū)?yīng)進(jìn)程的waiting channel信息,/proc//wchan,表示當(dāng)前線程D在這個(gè)函數(shù)位置。有時(shí)候可能是陷入內(nèi)核互斥鎖mutex,用戶(hù)空間叫futex。造成進(jìn)程D住的原因多種多樣,需要結(jié)合搜索引擎具體情況具體分析。進(jìn)一步還可以查看內(nèi)核當(dāng)前wchan的內(nèi)核調(diào)用棧,/proc/

  4. 由多個(gè)程序線程D狀態(tài)高導(dǎo)致。

    此時(shí)可能操作系統(tǒng)和所在機(jī)器整體出現(xiàn)了問(wèn)題,比如磁盤(pán)出現(xiàn)問(wèn)題。

    就有人解釋狀態(tài)D的含義是“Disk Sleep”,就比較生動(dòng)的說(shuō)明了這個(gè)問(wèn)題。

    實(shí)際造成的原因也是多種多樣。

深度好文:全面解析 Linux Load

總而言之,在實(shí)際生產(chǎn)中,造成load高的原因千差萬(wàn)別,還需要對(duì)linux內(nèi)核的各個(gè)模塊有深入的了解。

本文轉(zhuǎn)自公眾號(hào)“阿里智能運(yùn)維”,原文鏈接:深度好文-全面解析Linux Load。

Flink 作為當(dāng)今流計(jì)算最熱門(mén)技術(shù),全球規(guī)模最大 Flink 集群的運(yùn)維有哪些技術(shù)難點(diǎn)、痛點(diǎn)?11月1-2日,GOPS 2019 · 上海站,阿里巴巴大數(shù)據(jù) SRE 運(yùn)維技術(shù)專(zhuān)家王華帶來(lái)精彩分享,敬請(qǐng)期待。

分享到:
標(biāo)簽:Linux Load
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定