激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Linux|Centos|Ubuntu|系統(tǒng)進(jìn)程|Fedora|注冊表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服務(wù)器之家 - 服務(wù)器系統(tǒng) - Linux - 一文說清Linux System Load

一文說清Linux System Load

2021-12-15 23:09阿里技術(shù) Linux

雙十一壓測過程中,常見的問題之一就是load 飆高,通常這個時候業(yè)務(wù)上都有受影響,比如服務(wù)rt飆高,比如機器無法登錄,比如機器上執(zhí)行命令hang住等等。

一文說清Linux System Load

雙十一壓測過程中,常見的問題之一就是load 飆高,通常這個時候業(yè)務(wù)上都有受影響,比如服務(wù)rt飆高,比如機器無法登錄,比如機器上執(zhí)行命令hang住等等。本文就來說說,什么是load,load是怎么計算的,什么情況下load 會飆高,load飆高是不是必然業(yè)務(wù)受影響。

一 什么是load

我們平時所講的load,其全稱是Linux system load averages ,即linux系統(tǒng)負(fù)載平均值。注意兩個關(guān)鍵詞:一個是“負(fù)載”,它衡量的是task(linux 內(nèi)核中用于描述一個進(jìn)程或者線程)對系統(tǒng)的需求(CPU、內(nèi)存、IO等等),第二個關(guān)鍵詞是“平均”,它計算的是一段時間內(nèi)的平均值,分別為 1、5 和 15 分鐘值。system load average由內(nèi)核負(fù)載計算并記錄在/proc/loadavg 文件中, 用戶態(tài)的工具(比如uptime,top等等)讀的都是這個文件。

我們一般認(rèn)為:

  • 1、如果load接近0,意味著系統(tǒng)處于空閑狀態(tài);
  • 2、如果 1min 平均值高于 5min 或 15min 平均值,則負(fù)載正在增加;
  • 3、如果 1min 平均值低于 5min 或 15min 平均值,則負(fù)載正在減少;
  • 4、如果它們高于系統(tǒng) CPU 的數(shù)量,那么系統(tǒng)很可能遇到了性能問題(視情況而定)。

二 如何計算load

1 核心算法

坦白了不裝了,核心算法其實就是指數(shù)加權(quán)移動平均法(Exponential Weighted Moving Average,EMWA),簡單表示就是:

a1 = a0 * factor + a * (1 - factor),其中a0是上一時刻的值,a1是當(dāng)前時刻的值,factor是一個系數(shù),取值范圍是[0,1],a是當(dāng)前時刻的某個指標(biāo)采樣值。

為什么要采用指數(shù)移動加權(quán)平均法?我個人理解

  • 指數(shù)移動加權(quán)平均法,是指各數(shù)值的加權(quán)系數(shù)隨時間呈指數(shù)式遞減,越靠近當(dāng)前時刻的數(shù)值加權(quán)系數(shù)就越大,更能反映近期變化的趨勢;
  • 計算時不需要保存過去所有的數(shù)值,這對內(nèi)核非常重要。

我們來看看,內(nèi)核是怎么計算load average的,以下簡稱load。

上面的指數(shù)移動平均公式,a1 = a0 * e + a * (1 - e),具體到linux load的計算,a0是上一時刻的load,a1是當(dāng)前時刻的load,e是一個常量系數(shù),a 是當(dāng)前時刻的active的進(jìn)程/線程數(shù)量。

如上一節(jié)所述,linux 內(nèi)核計算了三個load 值,分別是1分鐘/5分鐘/15分鐘 load 。計算這三個load 值時,使用了三個不同的常量系數(shù)e,定義如下:

  1. #define EXP_1 1884 /* 1/exp(5sec/1min) */
  2. #define EXP_5 2014 /* 1/exp(5sec/5min) */
  3. #define EXP_15 2037 /* 1/exp(5sec/15min) */

這三個系數(shù)是怎么來的呢?公式如下:

  • 1884 = 2048/(power(e,(5/(60*1)))) /* e = 2.71828 */
  • 2014 = 2048/(power(e,(5/(60*5))))
  • 2037 = 2048/(power(e,(5/(60*15))))

其中e=2.71828,其實就是自然常數(shù)e,也叫歐拉數(shù)(Euler number)。

那為什么是這么個公式呢?其中,5是指每五秒采樣一次,60是指每分鐘60秒,1、5、15則分別是1分鐘、5分鐘和15分鐘。至于為什么是2048和自然常數(shù)e,這里涉及到定點計算以及其他一些數(shù)學(xué)知識,不是我們研究的重點,暫時不展開討論。

我們看看內(nèi)核中實際代碼:

  1. /*
  2. * a1 = a0 * e + a * (1 - e)
  3. */
  4. static inline unsigned long
  5. calc_load(unsigned long load, unsigned long exp, unsigned long active)
  6. {
  7. unsigned long newload;
  8. // FIXED_1 = 2048
  9. newload = load * exp + active * (FIXED_1 - exp);
  10. if (active >= load)
  11. newload += FIXED_1-1;
  12. return newload / FIXED_1;
  13. }

就是一個很直觀的實現(xiàn)。上面代碼中,第一個參數(shù)就是上一時刻的load, 第二個參數(shù)就是常量系數(shù),第三個參數(shù)是active的進(jìn)程/線程數(shù)量(包括runnable 和 uninterruptible)。

2 計算流程

load的計算分為兩個步驟:

1)、周期性地更新每個CPU上的rq里的active tasks,包括runnable狀態(tài)和uninterruptible狀態(tài)的task,累加到一個全局變量calc_load_tasks。

2)、周期性地計算 load,load的計算主要就是基于上述calc_load_tasks 變量。

第一個步驟,每個cpu都必須更新calc_load_tasks,但是第二個步驟只由一個cpu來完成,這個cpu叫tick_do_timer_cpu,由它執(zhí)行do_timer() -> calc_global_load()計算系統(tǒng)負(fù)載。

整體流程如下圖所示,在每個tick到來時(時鐘中斷),執(zhí)行以下邏輯:

一文說清Linux System Load

上圖中,棕色的calc_global_load_tick函數(shù)就是完成第一個步驟的,綠色的calc_global_load 是完成第二個步驟,藍(lán)色的calc_load 就是上一節(jié)中描述的核心算法。

這里需要說明的是,calc_global_load 把計算出來的load 值放在一個全局的變量avenrun中,它的定義是unsigned long avenrun[3],size 是3,用于存放1/5/15分鐘的load。 當(dāng)查看/proc/loadavg的時候,就是從這個avenrun數(shù)組中獲取數(shù)據(jù)。

三 load高常見原因

從上述load的計算原理可以看出,導(dǎo)致load 飆高的原因,說簡單也簡單,無非就是runnable 或者 uninterruptible 的task 增多了。但是說復(fù)雜也復(fù)雜,因為導(dǎo)致task進(jìn)入uninterruptible狀態(tài)的路徑非常多(粗略統(tǒng)計,可能有400-500條路徑)。個人覺得,有些地方有點濫用這個狀態(tài)了。

本人基于多年的linux 內(nèi)核開發(fā)和疑難問題排查經(jīng)驗,總結(jié)了一些經(jīng)驗,以饗讀者。

1 周期性飆高

曾經(jīng)有些業(yè)務(wù)方遇到過load周期性飆高的現(xiàn)象,如果不是因為業(yè)務(wù)上確實有周期性的峰值,那么大概率是踩中了內(nèi)核計算load時的bug。這個bug和內(nèi)核的load采樣頻率( LOAD_FREQ)有關(guān),具體細(xì)節(jié)不展開討論。這個bug在ali2016,ali3000, ali4000中已經(jīng)修復(fù)。

排除這個原因的話,可以接著查看是否磁盤IO的原因。

2 IO原因

磁盤性能瓶頸

iostat -dx 1 可以查看所有磁盤的IO 負(fù)載情況,當(dāng)IOPS 或者 BW 高時,磁盤成為性能瓶頸,大量線程因為等待IO而處于uninterruptible 狀態(tài),導(dǎo)致load飆高。此時如果用vmstat 查看,可能會觀察到 b 這一列的數(shù)值飆高, cpu iowait 飆高,/proc/stat文件中的procs_blocked 數(shù)值飆高。

云盤異常

云盤是虛擬盤,IO路徑長而復(fù)雜,比較容易出問題。常見的異常是IO UTIL 100%,avgqu-sz 始終不為0,至少有1 。大家不要誤解,io util 100%并不意味著磁盤很忙,而只意味著這個設(shè)備的請求隊列里在每次采樣時都發(fā)現(xiàn)有未完成的IO請求,所以當(dāng)某種原因?qū)е翴O丟失的話,云盤就會出現(xiàn)UTIL 100%, 而ECS內(nèi)核里的jbd2 線程,業(yè)務(wù)線程也會被D住,導(dǎo)致load 飆高。

JBD2 bug

JBD2是ext4 文件系統(tǒng)的日志系統(tǒng),一旦jbd2 內(nèi)核線程由于bug hang住,所有的磁盤IO請求都會被阻塞,大量線程進(jìn)入uninterruptible狀態(tài),導(dǎo)致load 飆高。

排除IO原因之后,接著可以查看內(nèi)存情況。

3 內(nèi)存原因

內(nèi)存回收

task 在申請內(nèi)存的時候,可能會觸發(fā)內(nèi)存回收,如果觸發(fā)的是直接內(nèi)存回收,那對性能的傷害很大。當(dāng)前task 會被阻塞直到內(nèi)存回收完成,新的請求可能會導(dǎo)致task數(shù)量增加(比如HSF線程池擴(kuò)容),load 就會飆高。 可以通過tsar --cpu --mem --load -i1 -l 查看,一般會觀察到sys cpu 飆高,cache 突降等現(xiàn)象。

內(nèi)存帶寬競爭

大家可能只聽說過IO帶寬,網(wǎng)絡(luò)帶寬,很少注意內(nèi)存帶寬。其實內(nèi)存除了在容量維度有瓶頸,在帶寬層面也有瓶頸,只是這個指標(biāo)普通的工具觀察不了。我們開發(fā)的aprof 工具可以觀察內(nèi)存帶寬競爭,在雙十一保障期間在混部環(huán)境大顯神威。

4 鎖

通常是內(nèi)核某些路徑上的spin_lock會成為瓶頸,尤其是網(wǎng)絡(luò)的收發(fā)包路徑上。可以用perf top -g 查看到spin_lock的熱點, 然后根據(jù)函數(shù)地址找到內(nèi)核的源碼。 伴隨的現(xiàn)象可能有sys 飆高,softirq 飆高。

另外,采用mutex_lock進(jìn)行并發(fā)控制的路徑上,一旦有task 拿著lock 不釋放,其他的task 就會以TASK_UNINTERRUPTIBLE的狀態(tài)等待,也會引起load飆高。但是如果這把鎖不在關(guān)鍵路徑上,那么對業(yè)務(wù)可能就沒啥影響。

5 user CPU

有些情況下load飆高是業(yè)務(wù)的正常表現(xiàn),此時一般表現(xiàn)為user cpu 飆高,vmstat 看到 r 這一列升高,tsar --load -i1 -l 看到runq 升高,查看proc/pid/schedstats 可能會看到第二個數(shù)字也就是sched delay 會增加很快。

四 根因分析大招

1 RUNNABLE 型load飆高分析

如上所述,這種情況,通常是由于業(yè)務(wù)量的增加導(dǎo)致的,屬于正常現(xiàn)象,但也有是業(yè)務(wù)代碼bug導(dǎo)致的,比如長循環(huán)甚至死循環(huán)。但無論哪一種,一般都可以通過熱點分析或者叫on cpu分析找到原因。on cpu分析的工具比較多,比如perf,比如阿里自研的ali-diagnose perf等等。

2 UNINTERRUPTIBLE型load飆高分析

所謂UNINTERRUPTIBLE,就是意味著在等,所以我們只要找到等在哪里,就基本找到原因了。

查找UNINTERRUPTIBLE狀態(tài)進(jìn)程

UNINTERRUPTIBLE,通常也稱為D狀態(tài),下文就用D狀態(tài)來描述。有一些簡單的工具可以統(tǒng)計當(dāng)前D狀態(tài)進(jìn)程的數(shù)量, 稍微復(fù)雜一點的工具可以把D狀態(tài)進(jìn)程的調(diào)用鏈也就是stack輸出。這類工具一般都是從內(nèi)核提供的proc 文件系統(tǒng)取數(shù)。

查看/proc/${pid}/stat 以及/proc/${pid}/task/${pid}/stat 文件,可以判斷哪些task 處于D狀態(tài),如下所示:

一文說清Linux System Load

第三個字段就是task的狀態(tài)。然后再查看/proc/${pid}/stack 文件就可以知道task 等在哪里。如:

一文說清Linux System Load

但有時候,D狀態(tài)的task 不固定,這會導(dǎo)致抓不到D狀態(tài)或者抓到stack的不準(zhǔn)確。這時候,就得上另一個終極大招,延遲分析。

延遲分析

延遲分析需要深入內(nèi)核內(nèi)部,在內(nèi)核路徑上埋點取數(shù)。所以這類工具的本質(zhì)是內(nèi)核probe,包括systemtap,kprobe,ebpf等等。但是probe 技術(shù)必須結(jié)合知識和經(jīng)驗才能打造成一個實用的工具。阿里自研的ali-diagnose可以進(jìn)行各種delay分析,irq_delay, sys_delay, sched_delay, io_delay, load-monitor。

五 總結(jié)

linux 內(nèi)核是一個復(fù)雜的并發(fā)系統(tǒng),各模塊關(guān)系錯綜復(fù)雜。但是就load 而言,只要從runnable task和 uninterruptible task兩個維度進(jìn)行分析,總能找到根源。

原文鏈接:https://zhuanlan.51cto.com/art/202112/695343.htm

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲第一成人在线视频 | 性欧美暴力猛交69hd | 国产成人精品区 | 欧美国产永久免费看片 | 91在线视频在线观看 | 久久久免费观看完整版 | 污黄视频在线播放 | 美女黄影院 | 日韩视频观看 | 最新亚洲国产 | 国产一区二区成人在线 | 91精品国产91 | 在线a毛片 | 在线高清中文字幕 | 叶子楣成人爽a毛片免费啪啪 | 欧美视频一区二区三区在线观看 | 久久久成人精品 | 国产精品久久久久久久久久大牛 | 久国产精品视频 | av在线一区二区三区 | 欧美一区二区黄 | 一级黄色在线免费观看 | 久久精品re | 成年人小视频在线观看 | 免费看真人a一级毛片 | 久久精品亚洲一区二区三区观看模式 | 黄色网址在线免费播放 | 久久久久北条麻妃免费看 | 久久蜜桃香蕉精品一区二区三区 | 久久久久九九九女人毛片 | 欧美日韩中文字幕在线视频 | 污片在线观看视频 | 毛片在线播放视频 | 91麻豆精品国产91久久久更新资源速度超快 | 伊人二本二区 | 成人一区二区三区四区 | 亚洲精品在线观看免费 | 精品一区二区三区免费看 | 手机国产乱子伦精品视频 | 福利在线免费视频 | 激情亚洲网 |