JVM診斷及工具筆記(5) cpu使用率方面的自助診斷
這篇文章描述了因為程序/單執行緒cpu瓶頸,導致Flink任務延遲的案例,並且分享了從最開始平臺工作人員手動去伺服器幫使用者診斷,再到如何賦能給使用者自助診斷的過程。
-
案例一:是TaskManager程序cpu使用率達到瓶頸的案例 (如果讀者生產環境未開啟cgroup可以跳過這個案例)
-
案例二:是TaskManager中某些執行緒的cpu使用率到達瓶頸的案例
現象及解決方案 :
平臺上Flink任務延遲,最初我們通過去伺服器上使用top + TaskManager的程序id命令,檢視TaskManager的CPU使用率是否到達瓶頸。
-
如果到達瓶頸,這個任務可能是cpu密集型的任務,引導使用者:
-
增加Flink任務的cpu核數或者並行度
-
通過火焰圖之類的工具分析程式碼是否需要優化
-
檢視任務是否fullgc (fullgc會佔用很多cpu資源)
-
-
如果未到達瓶頸,這個任務可能是io密集型的任務,引導使用者:
-
保持cpu核數不變,增加並行度,觀察是否改善
-
自助診斷方案 :
提供使用者TaskManager程序的cpu使用率 Metric,方便其自助分析任務是 cpu/io 密集型任務 ,進一步優化程式碼/任務資源。
具體實現 :
-
新增cpu使用率metric
方案: 一段時間內的 cpu使用時間/程式執行時間
-
上報cpu核數metric
Flink任務在多核環境執行,所以步驟一上報的cpu使用率metric數值經常都是>100%,需要除以CPU核數才能以0%-100%更加直觀地觀察cpu使用率。一般情況從Flink配置
yarn.containers.vcores
讀取cpu核數上報metric即可。
之家這邊實現了自動伸縮容功能,TaskManager的cpu核數有可能會有變化。這邊的方案是在申請TaskManager Container時,把cpu核數存到TaskManager的環境變數中。TaskManager啟動後從環境變數獲取cpu核數後上報metric即可。
-
最後配個將步驟1和步驟2的metric相除即可
案例二 :TaskManager 中某個執行緒cpu使用率瓶頸導致任務延遲
現象
-
top -Hp TaskManager程序號
TaskManager程序cpu使用率未耗盡,但是單執行緒的cpu使用率已到瓶頸。
-
printf '%x\n' 8845
獲取其執行緒對應系統的16進位制程序號 -
jstack -l TaskManager 程序號 |grep 228d
定位到這個執行緒
-
通過火焰圖發現消耗cpu的方法是這個udf
解決方案
-
優化udf
-
還可以拆開個執行緒這行邏輯到多個執行緒
-
新增並行度
自助診斷方案:
擴充套件個Flink的rest介面,整合到平臺,方便使用者可以自助去查詢TaskManager程序中cpu佔用較高的執行緒。可以借鑑JVM診斷神器arthas的 thread -n
命令實現
原理: 取樣一段時間 JVM每個執行緒的cpu使用時間 除以 這段JVM程式的執行時間 ,最終再排序 獲取top n 。
平臺上檢視 top 5執行緒使用率及執行緒棧詳情