火焰圖(Flame Graphs)的安裝和基本用法


火焰圖(Flame Graphs)

一、概述:

        火焰圖(flame graph)是性能分析的利器,通過它可以快速定位性能瓶頸點。

        perf 命令(performance 的縮寫)是 Linux 系統原生提供的性能分析工具,會返回 CPU 正在執行的函數名以及調用棧(stack)。

        本文介紹它的安裝和基本用法。

二、安裝perf和可視化生成器

# yum install perf -y           //yum方式安裝perf

# git clone https://github.com/brendangregg/FlameGraph.git               //選擇好火焰圖文件存放路徑后執行該條命令,從github上獲取火焰圖的相關文件,獲取完成后會有一個FlameGraph的文件夾,如下圖

 說明:打開文件夾,里面大部分是perf語言寫的腳本,生成火焰圖后續會用到,如下圖,右圖為各pl文件用途釋義

到此,安裝完成。

三、perf 采集數據

# perf record -F 99 -a -g -- sleep 60               //對CPU所有進程以99Hz采集,它的執行頻率是 99Hz(每秒99次),如果99次都返回同一個函數名,那就說明 CPU 這一秒鍾都在執行同一個函數,可能存在性能問題。執行60秒后會彈出如下圖提示表示采集完成,在當前目錄會生成一個perf.data的文件




# perf record -F 99 -p 181 -g -- sleep 60        //對進程ID為181的進程進行采集,采集時間為60秒,執行期間不要退出

上述代碼中perf record表示記錄,-F 99表示每秒99次,-p 13204是進程號,即對哪個進程進行分析,-g表示記錄調用棧,sleep 30則是持續30秒,-a 表示記錄所有cpu調用。更多參數可以執行
perf --help查看。
perf.data文件生成后,表示采集完成。最好是在火焰圖的目錄下進行采集,方便轉換成SVG圖形。

四、生成火焰圖

# perf script -i perf.data &> perf.unfold                        //生成腳本文件

# ./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded              

# ./FlameGraph/flamegraph.pl perf.folded > perf.svg                       //執行完成后生成perf.svg圖片,可以下載到本地,用瀏覽器打開 perf.svg,如下圖

 

 

五、火焰圖的含義

火焰圖是基於 perf 結果產生的 SVG 圖片,用來展示 CPU 的調用棧。

y 軸表示調用棧,每一層都是一個函數。調用棧越深,火焰就越高,頂部就是正在執行的函數,下方都是它的父函數。

x 軸表示抽樣數,如果一個函數在 x 軸占據的寬度越寬,就表示它被抽到的次數多,即執行的時間長。注意,x 軸不代表時間,而是所有的調用棧合並后,按字母順序排列的。

火焰圖就是看頂層的哪個函數占據的寬度最大。只要有"平頂"(plateaus),就表示該函數可能存在性能問題。

顏色沒有特殊含義,因為火焰圖表示的是 CPU 的繁忙程度,所以一般選擇暖色調。

六、互動性

火焰圖是 SVG 圖片,可以與用戶互動。

(1)鼠標懸浮

火焰的每一層都會標注函數名,鼠標懸浮時會顯示完整的函數名、抽樣抽中的次數、占據總抽樣次數的百分比。下面是一個例子。


mysqld'JOIN::exec (272,959 samples, 78.34 percent) 

(2)點擊放大

在某一層點擊,火焰圖會水平放大,該層會占據所有寬度,顯示詳細信息。

左上角會同時顯示"Reset Zoom",點擊該鏈接,圖片就會恢復原樣。

(3)搜索

按下 Ctrl + F 會顯示一個搜索框,用戶可以輸入關鍵詞或正則表達式,所有符合條件的函數名會高亮顯示。

七、火焰圖示例

下面是一個簡化的火焰圖例子。

首先,CPU 抽樣得到了三個調用棧。


func_c 
func_b 
func_a 
start_thread 

func_d 
func_a 
start_thread 

func_d 
func_a 
start_thread

上面代碼中,start_thread是啟動線程,調用了func_a。后者又調用了func_bfunc_d,而func_b又調用了func_c

經過合並處理后,得到了下面的結果,即存在兩個調用棧,第一個調用棧抽中1次,第二個抽中2次。


start_thread;func_a;func_b;func_c 1 start_thread;func_a;func_d 2 

有了這個調用棧統計,火焰圖工具就能生成 SVG 圖片。

上面圖片中,最頂層的函數g()占用 CPU 時間最多。d()的寬度最大,但是它直接耗用 CPU 的部分很少。b()c()沒有直接消耗 CPU。因此,如果要調查性能問題,首先應該調查g(),其次是i()

另外,從圖中可知a()有兩個分支b()h(),這表明a()里面可能有一個條件語句,而b()分支消耗的 CPU 大大高於h()

八、局限

兩種情況下,無法畫出火焰圖,需要修正系統行為。

(1)調用棧不完整

當調用棧過深時,某些系統只返回前面的一部分(比如前10層)。

(2)函數名缺失

有些函數沒有名字,編譯器只用內存地址來表示(比如匿名函數)。

九、常見應用的火焰圖

Node 應用的火焰圖

Node 應用的火焰圖就是對 Node 進程進行性能抽樣,與其他應用的操作是一樣的。


$ perf record -F 99 -p `pgrep -n node` -g -- sleep 30 

詳細的操作可以看這篇文章

Chrome 瀏覽器的火焰圖

Chrome 瀏覽器可以生成頁面腳本的火焰圖,用來進行 CPU 分析。

打開開發者工具,切換到 Performance 面板。然后,點擊"錄制"按鈕,開始記錄數據。這時,可以在頁面進行各種操作,然后停止"錄制"。

這時,開發者工具會顯示一個時間軸。它的下方就是火焰圖。

瀏覽器的火焰圖與標准火焰圖有兩點差異:它是倒置的(即調用棧最頂端的函數在最下方);x 軸是時間軸,而不是抽樣次數。

 

 

 

參考資料:

https://github.com/brendangregg/FlameGraph

http://www.brendangregg.com/flamegraphs.html

https://www.jianshu.com/p/492218c163d9

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

 

--------------------------------------------------------------------------------------------------------------------------------------------------------

歡迎從事性能測試的小伙伴加入性能測試Q群:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM