【性能】如何使用perf和火焰圖分析系統(tǒng)性能豹爹?

一裆悄、實驗環(huán)境

二、實驗案例分析


安裝完成后臂聋,我們先在第一個終端光稼,執(zhí)行下面的命令運行案例,也就是一個最基本的 Nginx 應(yīng)用:

?運行 Nginx 服務(wù)并對外開放 80 端口

# docker run -itd --name=nginx -p 80:80? nginx

然后逻住,在第二個終端钟哥,使用 curl 訪問 Nginx 監(jiān)聽的端口迎献,確認 Nginx 正常啟動瞎访。

假設(shè) 192.168.0.30 是 Nginx 所在虛擬機的 IP 地址,運行 curl 命令后吁恍,你應(yīng)該會看到下面這個輸出界面:

#??curl http://192.168.0.30/

接著扒秸,還是在第二個終端中,運行 hping3 命令冀瓦,模擬 Nginx 的客戶端請求:

#? hping3 -S -p 80 -i u10 192.168.0.30


現(xiàn)在伴奥,我們再回到第一個終端,你應(yīng)該就會發(fā)現(xiàn)異骋砻觯——系統(tǒng)的響應(yīng)明顯變慢了拾徙。

我們不妨執(zhí)行 top,觀察一下系統(tǒng)和進程的 CPU 使用情況:

從 top 的輸出中感局,你可以看到尼啡,兩個 CPU 的軟中斷使用率都超過了 30%;而 CPU 使用率最高的進程询微,正好是軟中斷內(nèi)核線程 ksoftirqd/0 和 ksoftirqd/1崖瞭。

雖然,我們已經(jīng)知道了 ksoftirqd 的基本功能撑毛,可以猜測是因為大量網(wǎng)絡(luò)收發(fā)书聚,引起了 CPU 使用率升高;但它到底在執(zhí)行什么邏輯,我們卻并不知道雌续。

對于普通進程斩个,我們要觀察其行為有很多方法,比如 strace驯杜、pstack萨驶、lsof 等等。但這些工具并不適合內(nèi)核線程艇肴,比如腔呜,如果你用 pstack ,或者通過 /proc/pid/stack 查看 ksoftirqd/0(進程號為 9)的調(diào)用棧時再悼,分別可以得到以下輸出:

那還有沒有其他方法核畴,來觀察內(nèi)核線程 ksoftirqd 的行為呢?

既然是內(nèi)核線程冲九,自然應(yīng)該用到內(nèi)核中提供的機制谤草。回顧一下我們之前用過的 CPU 性能工具莺奸,我想你肯定還記得 perf 丑孩,這個內(nèi)核自帶的性能剖析工具。

perf 可以對指定的進程或者事件進行采樣灭贷,并且還可以用調(diào)用棧的形式温学,輸出整個調(diào)用鏈上的匯總信息。?

我們不妨就用 perf 甚疟,來試著分析一下進程號為 9 的 ksoftirqd仗岖。


#? perf record -a -g -p 9 -- sleep 30

#################################################################

# man perf

# man 1 perf-record

perf-record - Run a command and record its profile into perf.data


-a, --all-cpus? ? ? ? System-wide collection from all CPUs (default if no target is specified).

-g? ? ? ? ? ? ? ? ? ? ? ? ? Enables call-graph (stack chain/backtrace) recording.

-p, --pid=? ? ? ?? ? ? Record events on existing process ID (comma separated list).

##################################################################

稍等一會兒,在上述命令結(jié)束后览妖,繼續(xù)執(zhí)行?perf report命令轧拄,你就可以得到 perf 的匯總報告。

按上下方向鍵以及回車鍵讽膏,展開比例最高的 ksoftirqd 后檩电,你就可以得到下面這個調(diào)用關(guān)系鏈圖:

從這個圖中,你可以清楚看到 ksoftirqd 執(zhí)行最多的調(diào)用過程府树。

雖然你可能不太熟悉內(nèi)核源碼俐末,但通過這些函數(shù),我們可以大致看出它的調(diào)用棧過程挺尾。



我們的猜測對不對呢鹅搪?

實際上,我們案例最開始用 Docker 啟動了容器遭铺,而 Docker 會自動為容器創(chuàng)建虛擬網(wǎng)卡丽柿、橋接到 docker0 網(wǎng)橋并配置 NAT 規(guī)則恢准。

這一過程,如下圖所示:

當(dāng)然了甫题,前面 perf report 界面的調(diào)用鏈還可以繼續(xù)展開馁筐。

不幸的是我的屏幕不夠大,如果展開更多的層級坠非,最后幾個層級會超出屏幕范圍敏沉。

這樣,即使我們能看到大部分的調(diào)用過程炎码,卻也不能說明后面層級就沒問題盟迟。


那么,有沒有更好的方法潦闲,來查看整個調(diào)用棧的信息呢攒菠?

火焰圖

針對 perf 匯總數(shù)據(jù)的展示問題,Brendan Gragg 發(fā)明了火焰圖歉闰,通過矢量圖的形式命斧,更直觀展示匯總結(jié)果贱除。

下圖就是一個針對 MySQL 的火焰圖示例衫生。

圖片來自 Brendan Gregg?博客??

這張圖看起來像是跳動的火焰采桃,因此也就被稱為火焰圖。


要理解火焰圖昼弟,我們最重要的是區(qū)分清楚橫軸和縱軸的含義:

上面 MySQL 火焰圖的示例啤它,就表示了 CPU 的繁忙情況,這種火焰圖也被稱為 on-CPU 火焰圖私杜。

如果我們根據(jù)性能分析的目標來劃分蚕键,火焰圖可以分為下面這幾種:

了解了火焰圖的含義和查看方法后救欧,接下來衰粹,我們再回到案例,運用火焰圖來觀察剛才 perf record 得到的記錄笆怠。


火焰圖分析


首先铝耻,我們需要生成火焰圖。我們先下載幾個能從 perf record 記錄生成火焰圖的工具蹬刷,這些工具都放在?https://github.com/brendangregg/FlameGraph?上面瓢捉。

你可以執(zhí)行下面的命令來下載:

#? git clone https://github.com/brendangregg/FlameGraph

#? cd FlameGraph

安裝好工具后,要生成火焰圖办成,其實主要需要三個步驟:

執(zhí)行 perf script 泡态,將 perf record 的記錄轉(zhuǎn)換成可讀的采樣記錄;

執(zhí)行 stackcollapse-perf.pl 腳本迂卢,合并調(diào)用棧信息某弦;

執(zhí)行 flamegraph.pl 腳本桐汤,生成火焰圖。


不過靶壮,在 Linux 中怔毛,我們可以使用管道,來簡化這三個步驟的執(zhí)行過程腾降。

假設(shè)剛才用 perf record 生成的文件路徑為 /root/perf.data拣度,執(zhí)行下面的命令,你就可以直接生成火焰圖:


# perf script -i? /root/perf.data | ./stackcollapse-perf.pl --all | ./flamegraph.pl > ksoftirqd.svg


執(zhí)行成功后螃壤,使用瀏覽器打開 ksoftirqd.svg 抗果,你就可以看到生成的火焰圖了。

如下圖所示:


根據(jù)剛剛講過的火焰圖原理奸晴,這個圖應(yīng)該從下往上看窖张,沿著調(diào)用棧中最寬的函數(shù)來分析執(zhí)行次數(shù)最多的函數(shù)。

這兒看到的結(jié)果蚁滋,其實跟剛才的 perf report 類似宿接,但直觀了很多,中間這一團火辕录,很明顯就是最需要我們關(guān)注的地方睦霎。


我們順著調(diào)用棧由下往上看(順著圖中藍色箭頭),就可以得到跟剛才 perf report 中一樣的結(jié)果:

不過最后走诞,到了 ip_forward 這里副女,已經(jīng)看不清函數(shù)名稱了。

所以我們需要點擊 ip_forward蚣旱,展開最上面這一塊調(diào)用棧:

這樣碑幅,就可以進一步看到 ip_forward 后的行為,也就是把網(wǎng)絡(luò)包發(fā)送出去塞绿。根據(jù)這個調(diào)用過程沟涨,再結(jié)合我們前面學(xué)習(xí)的網(wǎng)絡(luò)收發(fā)和 TCP/IP 協(xié)議棧原理,這個流程中的網(wǎng)絡(luò)接收异吻、網(wǎng)橋以及 netfilter 調(diào)用等裹赴,都是導(dǎo)致軟中斷 CPU 升高的重要因素,也就是影響網(wǎng)絡(luò)性能的潛在瓶頸诀浪。


不過棋返,回想一下網(wǎng)絡(luò)收發(fā)的流程,你可能會覺得它缺了好多步驟雷猪。

比如睛竣,這個堆棧中并沒有 TCP 相關(guān)的調(diào)用,也沒有連接跟蹤 conntrack 相關(guān)的函數(shù)求摇。實際上射沟,這些流程都在其他更小的火焰中嫉你,你可以點擊上圖左上角的“Reset Zoom”,回到完整火焰圖中躏惋,再去查看其他小火焰的堆棧幽污。

所以,在理解這個調(diào)用棧時要注意簿姨,從任何一個點出發(fā)距误、縱向來看的整個調(diào)用棧,其實只是最頂端那一個函數(shù)的調(diào)用堆棧扁位,而非完整的內(nèi)核網(wǎng)絡(luò)執(zhí)行流程准潭。

另外,整個火焰圖不包含任何時間的因素域仇,所以并不能看出橫向各個函數(shù)的執(zhí)行次序刑然。

到這里,我們就找出了內(nèi)核線程 ksoftirqd 執(zhí)行最頻繁的函數(shù)調(diào)用堆棧暇务,而這個堆棧中的各層級函數(shù)泼掠,就是潛在的性能瓶頸來源。這樣垦细,后面想要進一步分析择镇、優(yōu)化時,也就有了根據(jù)括改。


當(dāng)時腻豌,我們從軟中斷 CPU 使用率的角度入手,用網(wǎng)絡(luò)抓包的方法找出了瓶頸來源嘱能,確認是測試機器發(fā)送的大量 SYN 包導(dǎo)致的吝梅。而通過今天的 perf 和火焰圖方法,我們進一步找出了軟中斷內(nèi)核線程的熱點函數(shù)惹骂,其實也就找出了潛在的瓶頸和優(yōu)化方向苏携。

其實,如果遇到的是內(nèi)核線程的資源使用異常析苫,很多常用的進程級性能工具并不能幫上忙兜叨。這時,你就可以用內(nèi)核自帶的 perf 來觀察它們的行為衩侥,找出熱點函數(shù),進一步定位性能瓶矛物。當(dāng)然茫死,perf 產(chǎn)生的匯總報告并不夠直觀,所以我也推薦你用火焰圖來協(xié)助排查履羞。

實際上峦萎,火焰圖方法同樣適用于普通進程屡久。比如,在分析 Nginx爱榔、MySQL 等各種應(yīng)用場景的性能問題時被环,火焰圖也能幫你更快定位熱點函數(shù),找出潛在性能問題详幽。



CPU火焰圖和內(nèi)存火焰圖筛欢,在生成數(shù)據(jù)時有什么不同?

CPU 火焰圖和內(nèi)存火焰圖唇聘,最大的差別其實就是數(shù)據(jù)來源的不同版姑,也就是函數(shù)堆棧不同,而火焰圖的格式還是完全一樣的迟郎。

火焰圖的結(jié)構(gòu)是一樣的剥险,只是函數(shù)堆棧不一樣,內(nèi)存火焰圖側(cè)重于內(nèi)存管理函數(shù)的調(diào)用棧宪肖。


內(nèi)存火焰圖生成perf.data數(shù)據(jù)時表制,perf record加哪些選項?

要加上內(nèi)存管理相關(guān)的事件(函數(shù))控乾,比如 perf record -e syscalls:sys_enter_mmap -a -g -- sleep 60


三夫凸、參考


內(nèi)核線程 CPU 利用率太高,我該怎么辦阱持?

https://time.geekbang.org/column/article/86330


SVG 圖像入門教程

https://www.ruanyifeng.com/blog/2018/08/svg.html


SVG 簡介

https://www.runoob.com/svg/svg-intro.html


如何讀懂火焰圖夭拌?

http://www.ruanyifeng.com/blog/2017/09/flame-graph.html


Linux程序性能分析和火焰圖

https://www.cnblogs.com/pugang/p/10659301.html


Linux下用火焰圖進行性能分析

https://blog.csdn.net/gatieme/article/details/78885908


火焰圖介紹

https://book.aikaiyuan.com/linux/www.lijiaocn.com/linux/chapter1/04-flame-graphs.html


火焰圖性能分析 perf

https://www.jevic.cn/2019/03/03/perf


perf + 火焰圖分析程序性能

https://www.cnblogs.com/happyliu/p/6142929.html


使用 Perf 和火焰圖分析 CPU 性能

http://senlinzhan.github.io/2018/03/18/perf


利用火焰圖分析程序性能瓶頸

https://blog.angelmsger.com/%E5%88%A9%E7%94%A8%E7%81%AB%E7%84%B0%E5%9B%BE%E5%88%86%E6%9E%90%E7%A8%8B%E5%BA%8F%E6%80%A7%E8%83%BD%E7%93%B6%E9%A2%88

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衷咽,隨后出現(xiàn)的幾起案子鸽扁,更是在濱河造成了極大的恐慌,老刑警劉巖镶骗,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桶现,死亡現(xiàn)場離奇詭異,居然都是意外死亡鼎姊,警方通過查閱死者的電腦和手機骡和,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來相寇,“玉大人慰于,你說我怎么就攤上這事』缴溃” “怎么了婆赠?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長佳励。 經(jīng)常有香客問我休里,道長蛆挫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任妙黍,我火速辦了婚禮悴侵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拭嫁。我一直安慰自己可免,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布噩凹。 她就那樣靜靜地躺著巴元,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驮宴。 梳的紋絲不亂的頭發(fā)上逮刨,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音堵泽,去河邊找鬼修己。 笑死,一個胖子當(dāng)著我的面吹牛迎罗,可吹牛的內(nèi)容都是我干的睬愤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼纹安,長吁一口氣:“原來是場噩夢啊……” “哼尤辱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厢岂,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤光督,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后塔粒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體结借,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年卒茬,在試婚紗的時候發(fā)現(xiàn)自己被綠了船老。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡圃酵,死狀恐怖柳畔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辜昵,我是刑警寧澤荸镊,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站堪置,受9級特大地震影響躬存,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舀锨,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一岭洲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坎匿,春花似錦盾剩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至承桥,卻和暖如春驻粟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凶异。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工蜀撑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人剩彬。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓酷麦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親喉恋。 傳聞我的和親對象是個殘疾皇子沃饶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355