【作者介紹】
聞茂泉,阿里巴巴計算平臺事業(yè)部大數(shù)據(jù)基礎(chǔ)工程團隊SRE運維專家。通過閱碼場平臺將日常工作中積累的一些性能分析方面的經(jīng)驗,與打造的性能分析的工具跟大家一起做個分享。系統(tǒng)性能分析ssar工具已經(jīng)開源到了龍蜥社區(qū)。
說起性能分析就不得不提到《性能之巔》這本書,它是業(yè)界里程碑式的經(jīng)典書籍。在書中第4章觀測工具部分,Brendan告訴我們觀測工具主要包括:計數(shù)器(Counters)、跟蹤(Tracing)、采樣(Profiling)和監(jiān)控(Monitoring)幾大類。

依據(jù)數(shù)據(jù)獲取方式和數(shù)據(jù)實時性,將性能觀測工具做了分類:
1)左上角A區(qū)是直接讀取計數(shù)器實時數(shù)據(jù)的一些系統(tǒng)命令,top、ps這些命令我們都很常用,它們讀取的是/proc/這個目錄的信息,這里面的數(shù)據(jù)是內(nèi)核幫我們記賬出來的。
2)左下角B區(qū)也是基于計數(shù)器的?,但它是記錄歷史信息的工具,比如說最常用的就是sar工具,下文我們統(tǒng)稱這類工具為系統(tǒng)性能監(jiān)控工具。在阿里內(nèi)部也有tsar工具,國外還有開源軟件atop。系統(tǒng)性能監(jiān)控工具一方面可以回朔歷史數(shù)據(jù),同時也提供實時模式數(shù)據(jù)。
3)右上角C區(qū)跟蹤采樣工具,內(nèi)核的tracepoint,kprobe等就是跟蹤類工具,perf工具主要是采樣類工具,下文我們統(tǒng)稱這兩類工具為跟蹤采樣工具。目前這些工具都是只獲取實時的數(shù)據(jù)。如果不結(jié)合其他工具,單純使用它們來追查歷史數(shù)據(jù),它們是無法提供的。
4)右下角D區(qū),我們認為可以通過B區(qū)和C區(qū)的工具協(xié)同使用達到目標。
我們在性能分析工程實踐中重點聚焦在左下B區(qū)和右上C區(qū)藍框2個象限的建設(shè)上。今天我們主要探討的就是B區(qū)的系統(tǒng)性能監(jiān)控工具建設(shè)情況。以后再給大家介紹C區(qū)的工具建設(shè)情況。
系統(tǒng)性能監(jiān)控工具和跟蹤采樣工具各有優(yōu)勢和特點,我們認為應(yīng)該挖據(jù)各自潛力、發(fā)揮各自優(yōu)勢,讓他們都最大限度在系統(tǒng)性能分析工作中發(fā)揮恰當?shù)淖饔茫胁豢善H于任何一方。

在對系統(tǒng)性能監(jiān)控和跟蹤采樣工具的具體理解上,我們認同如下3個理念:
1)內(nèi)核計數(shù)器(Counters)信息獲取代價低,無額外開銷。相比較而言,跟蹤采樣工具或多或少都有一些運行開銷,如kprobe的使用還可能會引起一些穩(wěn)定性風險。因此,我們傾向于最大化挖掘計數(shù)器信息的價值,給跟蹤采樣工具減負。比如要獲知機器直接內(nèi)存回收的信息時,內(nèi)核計數(shù)器已經(jīng)提供了更低代價獲取的直接內(nèi)存回收和異步內(nèi)存回收的指標,就完全沒必要使用ftrace監(jiān)控直接內(nèi)存回收的情況了。另一方面,對于內(nèi)核計數(shù)器不能涵蓋的細顆粒度內(nèi)核數(shù)據(jù),還必須要依賴內(nèi)核跟蹤采樣工具獲取。比如當IOPS較高時,我們想了解具體的每一個IO讀寫的具體文件信息,內(nèi)核計數(shù)器中完全沒有相關(guān)信息。只有讓跟蹤采樣工具專注于自己的核心任務(wù),才更有條件打磨出更加穩(wěn)定和可靠的產(chǎn)品級工具方案。畢竟只專注于2件事,比同時干10件事更容易干的出色。
2)現(xiàn)有的系統(tǒng)性能監(jiān)控工具,除單機監(jiān)控工具外,還有很多白屏化的監(jiān)控平臺。白屏化監(jiān)控平臺一般都是將數(shù)據(jù)采集到中心數(shù)據(jù)庫,然后再集中展示。白平化監(jiān)控平臺采集更詳細的計數(shù)器信息時,總會遇到存儲成本的壓力的問題,因此不宜將過多計數(shù)器指標采集到白屏化監(jiān)控平臺。但同時對于一些高頻使用的常規(guī)指標,如CPU、內(nèi)存和網(wǎng)絡(luò)使用率情況,使用白屏化監(jiān)控平臺展示,確實可以大大提升可觀測性。所以高頻常規(guī)指標使用白屏化監(jiān)控平臺的同時,仍然需要依賴一個數(shù)據(jù)更加豐富的黑屏系統(tǒng)性能監(jiān)控工具作為補充,以應(yīng)對一些關(guān)鍵時刻必須依賴的低頻計數(shù)器數(shù)據(jù)。
3)傳統(tǒng)的黑屏系統(tǒng)性能監(jiān)控工具,多年來一直相對比較固化,歷數(shù)2010年、2015年、2020年指標內(nèi)容變化不是特別大。舉個例子,新版本內(nèi)核的計數(shù)器中,網(wǎng)絡(luò)擴展指標多達400多個,僅TCP擴展指標就有116個,但是實際上常規(guī)的系統(tǒng)性能監(jiān)控在TCP網(wǎng)絡(luò)指標這一塊,也就使用了不超過15個指標,大部分指標價值并沒有被挖掘出來。這些網(wǎng)絡(luò)的內(nèi)核計數(shù)器指標,在很多網(wǎng)絡(luò)相關(guān)問題發(fā)生時,都特別有使用價值。
基于這些理念,我們認為研發(fā)一款數(shù)據(jù)指標更全、迭代周期更短、性能更加穩(wěn)定的系統(tǒng)性能監(jiān)控工具,以應(yīng)對日益復雜系統(tǒng)性能問題是很必要的。
今天我們要介紹的阿里自研ssar工具,就是這樣一款系統(tǒng)性能監(jiān)控類工具,并且已經(jīng)在知名的操作系統(tǒng)社區(qū)龍蜥開源。它幾乎涵蓋了傳統(tǒng)系統(tǒng)性能監(jiān)控sar工具的所有功能,同時擴展了更多的整機級別的指標,新增了進程級指標和特色的load指標,load高問題的診斷是這個工具一個獨特的功能。
開源軟件atop也是這樣一個類似功能的系統(tǒng)性能監(jiān)控工具。公開渠道了解到友商也在大規(guī)模部署atop工具,這說明在業(yè)界其他互聯(lián)網(wǎng)公司也感受到了擁有這樣一個功能定位的監(jiān)控工具的重要性。
下文我會用幾個例子說明我們是如何結(jié)合使用系統(tǒng)性能監(jiān)控工具和跟蹤采樣工具的。
系統(tǒng)性能監(jiān)控工具ssar開源地址:
https://gitee.com/anolis/tracing-ssar.git
其中Reference_zh-CN.md是詳細的中文幫助手冊,package目錄中有rpm和deb包提供,其他操作系統(tǒng)可以自行編譯打包。

ssar工具分為采集器、內(nèi)層的通用查詢器、外層的增強查詢器和經(jīng)典查詢器幾部分。
1)采集器sresar:C語言實現(xiàn)的一個常駐進程,將數(shù)據(jù)記錄到本地磁盤,采集數(shù)據(jù)內(nèi)容包括:
???(a) 按文件單位采集的整機數(shù)據(jù),meminfo、stat、vmstat等;
???(b) 包含24個指標的進程級數(shù)據(jù);
???(c) 獨特的load5s指標和詳細的R或D狀態(tài)線程詳情數(shù)據(jù);
2)通用查詢器ssar命令:c++語言實現(xiàn),負責按文件名、某行、某列等通用規(guī)則對文件數(shù)據(jù)進行邏輯解析。
3)古典查詢器tsar2:python語言實現(xiàn),對ssar命令進行封裝,全面兼容tsar命令;
4)增強查詢器ssar+:python語言實現(xiàn),對ssar命令進行封裝,規(guī)劃上是未來ssar工具的主要核心,適合于把較復雜的數(shù)據(jù)邏輯放在python語言實現(xiàn)層。
傳統(tǒng)sar工具只采集一些固定指標。在使用C語言采集的同時進行指標解析的模式下,不是極難擴展新指標,就是擴展新指標迭代周期特別長。
ssar工具完全顛覆了傳統(tǒng)sar工具的架構(gòu)設(shè)計,在產(chǎn)品設(shè)計和程序架構(gòu)上做了很多變化,可以讓我們快速、低成本的增加新的計數(shù)器指標。
1)如果我們關(guān)注一個新的指標,但是又沒有被采集。對于修改傳統(tǒng)的系統(tǒng)性能監(jiān)控工具sar來說,修改發(fā)布迭代周期是非常長的,發(fā)布下來可能要數(shù)周到數(shù)月。在學習內(nèi)核知識或者解決生產(chǎn)問題的時候,新問題等不起這么久。但ssar工具以文件為采集單位,不需要修改代碼,直接改一下配置文件,重啟srerar采集進程就可以采集一個新的數(shù)據(jù)源文件。新增采集文件可在sys.conf文件中的file區(qū)域增加一行配置項,其中sre_path為數(shù)據(jù)源位置,cfile為數(shù)據(jù)文件存儲名,turn為開啟采集。

2)ssar把一些通用處理邏輯都抽象到ssar命令通用查詢器里,配置文件采集后,只需一條ssar命令查詢顯示數(shù)據(jù),完美實現(xiàn)分鐘級周期的迭代。其中cfile指定存儲文件名,line指定第3行,column指定第5到15行,metric指定顯示原值,alias指定指標名稱。

3)更加復雜的邏輯,ssar把它轉(zhuǎn)移到外層python語言的查詢器中實現(xiàn)。這個時候你很容易通過在python中的修改來適應(yīng)數(shù)據(jù)解析的變化。內(nèi)核中有些指標伴隨著內(nèi)核版本的變化格式也在變化,比如TCP的TimeWaitOverflow指標在3.10、4.9和4.19版中所處的列數(shù)就不同。此時可以python語言中輕松獲取column值,傳遞給ssar通用查詢器。即使面對未來內(nèi)核版本中的未知變化,我們也可以通過python查詢器應(yīng)付自如。可隨時調(diào)試和升級python查詢器,如cp tsar2 ?/tmp/test.py,不論是單機環(huán)境debug,還是腳本批量下發(fā),均可輕量級操作。
相比較傳統(tǒng)系統(tǒng)性能監(jiān)控工具,ssar的特點是能記錄更加豐富的計數(shù)器 (Counters) 指標信息,但這也會占用更多的磁盤存儲空間。ssar工具默認記錄7天歷史數(shù)據(jù),通常占用磁盤空間不超過1GB。近20年來,隨著存儲技術(shù)的發(fā)展,單位空間的磁盤存儲成本價格下降到千分之一。適當提高系統(tǒng)性能監(jiān)控工具的采集數(shù)據(jù)量是有一定可行性的。
為了追求更加完美的磁盤空間穩(wěn)定性,ssar仍然設(shè)計了更加積極的磁盤存儲空間策略。還設(shè)置了專門的參數(shù),當磁盤空間使用率達到閾值(默認90%)后,會停止數(shù)據(jù)采集。不但如此,當由于其他進程原因使磁盤空間數(shù)據(jù)繼續(xù)增長并超過90%時,ssar會啟動對7天內(nèi)較早歷史數(shù)據(jù)的刪除工作,直到磁盤空間使用率小于90%或?qū)sar歷史數(shù)據(jù)基本刪除。
用圖示表示,圖中藍色的部分就是A、B、C、D中各臺機器的原來磁盤空間使用情況,有多些的,有少些的。

傳統(tǒng)的系統(tǒng)性能監(jiān)控工具會占用每臺機器固定的磁盤存儲空間,相當于不區(qū)分各個機器的磁盤空間使用現(xiàn)狀,每臺機器都增加圖中紅色部分的磁盤空間占用。當系統(tǒng)性能監(jiān)控工具采集數(shù)據(jù)量較大后,必須重新規(guī)劃磁盤分區(qū)的存儲空間。

ssar系統(tǒng)性能監(jiān)控工具,使用的是圖中這個綠色區(qū)域的存儲空間。無需重新規(guī)劃磁盤分區(qū)的存儲空間。

實際生產(chǎn)中磁盤空間的規(guī)劃,一般都會保留一定的free空間作為buffer,應(yīng)對突發(fā)情況。傳統(tǒng)系統(tǒng)性能監(jiān)控工具所在磁盤分區(qū)必須相應(yīng)的規(guī)劃一個額外的磁盤空間,而ssar工具的這種磁盤空間處理邏輯不用規(guī)劃額外的磁盤空間。唯一的缺點就是磁盤打滿同時又需要消費ssar數(shù)據(jù)的場景,但這個場景概率極低。
傳統(tǒng)的系統(tǒng)性能監(jiān)控工具中的load1指標盡管比load5和load15指標更精準,仍然不能滿足排查問題時的時間維度的精準度要求。ssar在國內(nèi)外全行業(yè)獨創(chuàng)了load5s指標,該指標可以讓我們將load的準確性提升到5秒級的精度。load5s指標的準確性絕不僅體現(xiàn)在采集頻率上,簡單說load5s指標就是R+D的線程數(shù),也是內(nèi)核數(shù)據(jù)結(jié)構(gòu)中的全局變量active值。
下面通過一個實驗來帶大家理解load5s指標。我們找一臺實驗機器,我們在終端窗口A查看load,沒有任何負載壓力load1非常低。我們現(xiàn)在再開一個終端窗口B,運行一個模擬負載壓力的命令,命令內(nèi)容是“stress -t 40 -c 1000”,其中stress命令需要自己安裝。stress 命令主要用來模擬系統(tǒng)負載較高時的場景,這里并發(fā)啟動1000個消耗CPU資源的單線程進程,就是1000個線程,并且控制只運行40秒后就停止。我們測試的stress命令是15分10秒執(zhí)行的,經(jīng)過40秒就是15分50秒結(jié)束。stress命令執(zhí)行結(jié)束后,我們再回到終端A使用ssar load5s命令查看運行效果。

依次分析實驗的結(jié)果:
1)綠色時間區(qū)域15分09秒時,load5s和load1都還處于一個低水位,毫無疑問說明當時機器負載壓力很低。
2)伴隨著15分10秒stress命令開始執(zhí)行后,紅色時間區(qū)域load5s和load1都同時升高, 15分14秒采集時刻,load5s值已經(jīng)達到1003,load1開始升高到80.4,但是這個load1的值遠遠不能體現(xiàn)出當前機器上并發(fā)運行1000個負載壓力的線程的狀況。隨著時間的推移,15分46秒這個時刻,load1的值緩慢升到了489.16。
3)15分50秒1000個stress并發(fā)進程退出,在藍色時間區(qū)域15分52秒這個時刻的load5s值也同時迅速降低到了很低的值0。但是我們看到15分52秒這個時刻的load1值,依然有449.99這么高,這里的load1值看上去是及其令人迷惑的。
上面這個實驗說明load5s才是更準確反映系統(tǒng)負載壓力的指標,而單純用load1值判斷機器的負載是不準確的。所以我們需要用load5s指標替代load1指標來精準判斷機器負載發(fā)生的時間范圍。除load5s指標外,上面的解決方案中,還提供了一組指標用于全面的評估系統(tǒng)負載情況。其中l(wèi)oad5s是R+D狀態(tài)的線程數(shù)之和,runq是當時的R狀態(tài)線程數(shù),threads是所有狀態(tài)線程數(shù)總和,因此threads值是load5s值的天花板,threads最大值受內(nèi)核參數(shù)設(shè)置限制。
ssar工具還會根據(jù)load5s和CPU核數(shù)之比,來觸發(fā)對load詳情的采集,前邊的actr是采集到并發(fā)的R狀態(tài)線程數(shù),actd是采集到并發(fā)的D狀態(tài)線程數(shù),act是actr和actd數(shù)之和。當我們需要了解load構(gòu)成的詳細因素時,可以借助load2p子命令進一步顯示actr和actd的詳情數(shù)據(jù)。
雖然load5s指標體系能如此精準的反應(yīng)系統(tǒng)的負載壓力情況,但我們并沒有依賴kprobe、ebpf等任何跟蹤采樣技術(shù)。load5s指標完全在用戶態(tài)通過工程化的方法巧妙獲取,充分體現(xiàn)了我們“最大化挖掘計數(shù)器歷史信息價值”的理念。
如此神奇的load5s指標,在最初的發(fā)現(xiàn)和理解過程,還曾經(jīng)深入借助了跟蹤采樣工具的支持,下面按時間線來回顧下這個歷程。
1)首先結(jié)合systemtap工具的使用,同時閱讀內(nèi)核load部分的內(nèi)核代碼,了解到linux load的計算邏輯是在calc_global_load函數(shù)中獲取一個active全局變量(active包含R和D兩種狀態(tài)的線程數(shù)量),然后按照每隔5秒鐘的頻率采樣,最后由近及遠按不同權(quán)重計算出load值。歸納起來的公式就是:
load1(n)??=func1(load1(n-1), active(n))
load1(n-1) ?=func1(load1(n-2), active(n-1))
當前的這個load1值,是拿5秒鐘前的上一個load1跟當前時刻這個active值做一個計算得出來的。那上一個時刻load1值就是上上一個時刻load1值和上一個時刻active值計算出來的,所以這是一個無限遞歸的過程。
2)遺憾的是內(nèi)核并沒有暴露active變量值,但我們可以借助一個kprobe內(nèi)核模塊hook內(nèi)核變量并通過proc接口暴露給用戶空間。可參考本人較早文章《深度好文:全面解析 Linux Load 》,其中有如下代碼:
git clone https://github.com/os-health/load5s.git
通過暴露的內(nèi)核變量值,運行l(wèi)oad預測腳本,按照內(nèi)核里面load的計算方法,在用戶空間重算一遍load值,結(jié)果如圖。

看到內(nèi)核吐出的current_load值25.07和我們shell腳本預測的predict_load值25.07完全一樣,說明在load_predict.sh腳本中計算邏輯就是內(nèi)核對load值的計算邏輯。這個預測值25.07是根據(jù)上一個load1值24.38和load5s值的33(load5s就是active值)計算而來。
3)由此,我們完全可以反其道而行。既然是這個25.07是通過這24.38和33這兩個值算出來的,我們完全可以監(jiān)控這個load1的值的變化,然后每5秒鐘去把這個active值反算出來就可以了。
active(n)???= func2(load1(n)?,?load1(n-1))
通過在用戶空間反算active值,使其在工程上具有極大的通用性和可靠性,我們將active值命名為load5s。
在load高的各種場景中,有一種R狀態(tài)線程數(shù)并發(fā)多的load高是由于sys CPU使用率偏高引起的。ssar全面的指標體系,從多個角度將這種場景發(fā)生過程進行了透徹的呈現(xiàn)。
為了準確的說明問題,有必要回顧下內(nèi)核內(nèi)存回收的相關(guān)概念。如圖所示,當整機free內(nèi)存低于黃線low閾值時,內(nèi)核異步內(nèi)存回收線程kswapd開始被喚醒,kswapd會在其他進程申請內(nèi)存的同時回收內(nèi)存。當整機free內(nèi)存到達紅線min閾值時,觸發(fā)整機直接內(nèi)存回收,所有來自用戶空間的內(nèi)存申請將被阻塞住,線程狀態(tài)同時轉(zhuǎn)換為D狀態(tài)。此時只有來自內(nèi)核空間的內(nèi)存申請可以繼續(xù)使用min值以下的free內(nèi)存。后續(xù)當整機free內(nèi)存逐步恢復到綠線high閾值以上后,kswapd線程停止內(nèi)存回收工作。

下面以ssar的數(shù)據(jù)指標為依據(jù),一步一步的展示了當整機內(nèi)存緊張后是如何引起sys CPU高,并進而引發(fā)load高的完整過程:
1)用戶空間java進程在20點43分到20點45分2分鐘內(nèi)大量申請24GB內(nèi)存;

2)整機內(nèi)存used在20點43分到20點45分2分鐘內(nèi)迅速增長了26GB,同時整機free內(nèi)存迅速減少了14GB;

3)free內(nèi)存在20點45分時只有3GB,低于low閾值,pgscan_kswapd/s值非0表明觸發(fā)kswapd異步內(nèi)存回收。

4)kswapd異步內(nèi)存回收跟不上進程內(nèi)存申請的速度,當free內(nèi)存達到min閾值時,pgscan_direct/s值非0表明觸發(fā)直接內(nèi)存回收,用戶空間內(nèi)存申請進程D住。棧頂函數(shù)sleep_one_page和congestion_wait等都是典型的直接內(nèi)存回收時的特征。

5)20點44分到20點45分出現(xiàn)大量網(wǎng)絡(luò)吞吐,每秒進出流量分別達到1.5G和1.0G。網(wǎng)絡(luò)流量吞吐會伴有內(nèi)核空間內(nèi)存申請,繼續(xù)消耗min閾值以下(橙色部分)free內(nèi)存。

6)內(nèi)核網(wǎng)絡(luò)模塊會申請order3階內(nèi)存,20點45分時刻buddyinfo中order3以上高階內(nèi)存消耗殆盡,剩余的3GB free內(nèi)存處于碎片化狀態(tài)。內(nèi)核空間申請的內(nèi)存是連續(xù)內(nèi)存,雖然order2和order1有庫存,但申請order3時是無法被分配的,內(nèi)核只能處于忙等狀態(tài)。

7)觸發(fā)內(nèi)核態(tài)忙等,同時會引發(fā)20點44分到20點45分的sys CPU升高,sys CPU平均每秒占總CPU資源的89.61%,擠占用戶空間既有進程CPU資源,同期用戶態(tài)CPU使用從原來的72.59%降低到7.73%。

8)觸發(fā)直接內(nèi)存回收時,會引發(fā)大量D狀態(tài)線程,后續(xù)order3庫存枯竭引發(fā)sys CPU高后,會繼續(xù)引發(fā)大量R狀態(tài)線程。load5s子命令看到的現(xiàn)象就是先出現(xiàn)load5s指標升高,再出現(xiàn)load5s和runq同時升高。

以上各指標立體的展現(xiàn)了整機內(nèi)存不足時,如何引發(fā)load高的機制。有人也許會好奇,一開始是如何將這些指標關(guān)聯(lián)到一起的。高階內(nèi)存不足引起sys CPU異常的場景,在問題調(diào)查早期也的確是通過采樣(Profiling)工具火焰圖獲取的直接線索。在火焰圖熱點函數(shù)棧中有__alloc_skb這樣函數(shù),再結(jié)合內(nèi)核代碼,之后才想到補充buddyinfo內(nèi)核計數(shù)器指標觀察order0到order10的情況。
補充buddyinfo計數(shù)器指標后,再遇到sys CPU高問題,通過以上指標體系就直接可以判斷了,不用再次使用采樣工具(perf)。
終于有一天,sys CPU又打高了,但是并沒有同時出現(xiàn)內(nèi)存相關(guān)指標的異常,只發(fā)現(xiàn)占用sys CPU的是大量內(nèi)核線程kworker。

這時還需要繼續(xù)借助采樣(Profiling)工具獲取火焰圖分析。

根據(jù)火焰圖中熱點函數(shù)ext4_mb_regular_allocator/ext4_mb_good_group,再結(jié)合sys CPU占用率高的進程是kworker,結(jié)合內(nèi)核代碼可以看到這是文件系統(tǒng)方面的函數(shù),在分配空閑塊。自然就會去想到查看磁盤空間指標,發(fā)現(xiàn)確實出現(xiàn)了100%的情況發(fā)生。

這是本文第二個例子體現(xiàn)了“最大化挖掘計數(shù)器歷史信息價值,發(fā)揮計數(shù)器指標和跟蹤采樣工具各自的優(yōu)勢”的理念。
本文舉的第三個例子,是關(guān)于nvme協(xié)議的SSD盤的。這種盤IO性能很高,有時候會遇到讀的IOPS高達上萬的情況,磁盤IO Util打到100%,而且單IO size特別小只有4KB。

阿里有一個自研的IO跟蹤工具,可以抓到每一個IO讀寫了那個文件。最初出現(xiàn)這種IO打滿情況時,我們使用阿里自研的IO跟蹤工具抓取了每一個IOPS的詳情,發(fā)現(xiàn)讀取的文件都是二進制的so包,而且分析扇區(qū)地址Sector信息時發(fā)現(xiàn)同一個扇區(qū)地址平均最多每秒被重復讀取了178次,這是非常不符合常規(guī)的。正常情況下,我們的程序是一次性從磁盤加載到內(nèi)存空間,不會重復加載,但是這里一秒鐘重復加載178次,說明一秒內(nèi)又被丟棄了177次。問題調(diào)查到這里,我們自然想去查看內(nèi)存方面的問題。

經(jīng)分析最終確認是cgroup的內(nèi)存設(shè)置問題,該進程的memory.limit_in_bytes設(shè)置為4GB,當前進程的rss內(nèi)存使用已經(jīng)到了3.9GB,剩余的100MB空間不足以完全加載800MB的clean 狀態(tài)的二進制可執(zhí)行代碼部分。先加載第一個100MB的代碼段,當開始執(zhí)行第二個100MB的代碼段時,必須釋放一些第一個100MB的代碼段。如此就會出現(xiàn)反復加載同一個扇區(qū)地址代碼段的情況。
了解了這種場景的原理,會發(fā)現(xiàn)出現(xiàn)這種場景時整機和進程級別的主缺頁中斷數(shù)會大量增加。當再次出現(xiàn)磁盤讀IO異常高時,我們可以不依賴IO跟蹤工具,直接查看整機主缺頁中斷數(shù),判斷是否又發(fā)生了內(nèi)存顛簸。

當確定時發(fā)生內(nèi)存顛簸時,再進一步通過ssar進程級指標確定大量發(fā)生主缺頁中斷的進程。通過pid查看進程cgroup中memory.limit_in_bytes 值的設(shè)置,并對比進程當前的rss值也可以診斷這類問題。并且這類問題不論發(fā)生在任何時間,都可以通過ssar指標輕松診斷。

前面在linux load、sys CPU和IOPS的性能分析過程中,分享了3個案例。這3個案例都貫穿了一個性能分析的思路,最大化挖掘計數(shù)器歷史信息的價值,解放跟蹤采樣工具。使用跟蹤采樣工具探索發(fā)現(xiàn)問題的內(nèi)在邏輯后,再將相關(guān)計數(shù)器指標固化到ssar系統(tǒng)性能監(jiān)控工具中。