CPU 利用率異常的分析思路和方法 (來自社區會員交流活動,社區專家楊建旭總結梳理成文)
常見CPU問題總結就是這幾類:
1、CPU使用率過高
2、CPU使用率太低
3、CPU使用率各核使用不均衡
分析的基礎是監控,監控項可參考:性能測試監控——CPU
在生產運行當中,經常會遇到CPU利用率異常或者不符合預期的情況,下面這些知識可以幫助你。
1
基本概念類問題
(一) CPU的占用是怎么產生的?為什么不同OS下的CPU利用率不同?
操作系統是用來調度任務(進程)和管理外圍設備的系統,操作系統采用自己的進程調度策略將進程調度到CPU上運行,占用了CPU時間片,由此產生了CPU的占用。
為什么不同OS下的CPU利用率不同呢?有以下幾方面的原因:
1. 不同的操作系統管理外圍設備的方法、進程調度的算法、內存管理的算法等等有差異,因此同一個應用在不同的OS下的CPU消耗可能不一樣。
2. 同一個應用安裝在不同的設備上(包括硬件+OS+系統軟件),並不能保證參數都是一樣的。即使是同一個版本的OS,由於應用和OS的參數配置太多,可能某個參數配的不一樣,相差很大的CPU利用率都是可能的。舉幾個例子:
-
一個采用文件系統,另一個采用裸設備
-
一個設置了CPU折疊,一個沒設置
-
一個寫磁盤是按照4K寫入,另一個按照64K寫入,那么diskbusy的百分比相差很大,CPU的繁忙程度也略有不同
3. 不同OS上,CPU數讀工具的統計方法可能不一樣,即使是同一個OS,不同的CPU讀數工具的統計方法也可能不一樣。
有人提到,“Linux on Power的處理器利用率比AIX的處理器利用率相比少得多”,這個現象並不奇怪。即使都是AIX,同一個應用在AIX61上和AIX71上,CPU利用率也不同,我做過實驗,AIX71相比AIX61做了一定的優化。
(二) 為什么多核CPU的利用率分布不均勻
問題:在AIX系統,利用topas查看時,發現只有一個CPU的利用率很高,其他的core利用率幾乎為零,怎么可以調整參數,使得其他的core的利用率增大?在Linux下的問題同樣的疑問。
從應用角度,很可能應用是個單進程,不能分到多個CPU上運行。如果已經是個多進程應用,那就可能並發數設置為1了,需調大並發數后才能分配到多個核運行。
從操作系統層面,系統會把進程調度到上一次使用的CPU,以避免進程的上下文切換。一個CPU干的好好的,當然不會調到其他CPU,不然上下文切換代價大。因此,如果壓力不是很大的時候,當然是只有一個core的利用率較大,而其他core是閑置狀態。
(三) CPU利用率的正常使用范圍是多少?
一般來說,生產運行環境中CPU 70%會報警。有些謹慎、保守的單位,CPU超過40%就着手擴容了。
但並不是說CPU一超過70%就一定是異常,對於夜間的批處理業務,可能更多的是期望它盡多占用CPU、盡快處理完成,以免影響第二天的開門。
(四) CPU利用率當中的Sys%高是什么原因?
如果系統態占比比較大,一般有以下幾類原因:
1. 為了追求效率,減少用戶態到系統態的轉換,把用戶態的function改到系統態,例如:一些驅動程序,以顯卡驅動最為常見
2. 系統有IO問題
3. 應用設計問題
例1:頻繁調用sync函數做緩存到磁盤的數據同步,就會產生大量sys%,並且這個sys%中,大量的是kernel態的wait和sync。
例2:反復load/unload so文件。
例3:阻塞方式的網絡收發
2
問題診斷思路
(一) CPU利用率上不去
CPU有兩頭怕
1)怕CPU占用率高
2)怕CPU占用率低
重點解釋一下為什么怕CPU低。有時候,業務壓力沖上來了,但都被擋在外面,或者堆在隊列了,而此時看CPU利用率卻很低,也就是有CPU但沒有用上。
這種情況有好多原因,這里說幾個原因:
1)並發線程數太少
並發數應該開多少呢? 假如你的應用線程是全力干活的線程,沒有什么SLEEP、等IO之類的事情,也就是說,一個線程可以把一個物理CPU THREAD吃的滿滿的。那么你的最大並發線程,可以設為略小於服務器的邏輯CPU數量。也就是CPU CORE* SMT。如果你是虛擬化POWERVM環境,邏輯CPU=VPSMT,但虛擬化環境,需要額外注意,如果你要保持高性能,那么建議略小於ECSMT即可。
2)虛擬化平台的參數配置有問題
比如某個LPAR,EC=0.5,VP=5,那么很可能,壓力來了之后,CPU利用率也上不去,報文嚴重堆積。因為可能系統環境中物理機的CPU占用率已經較高,各個LPAR之間借用CPU已經非常嚴重,大部分時間都花在hypervisor的調度上,以及CPU的cache命中失敗去內存找數據取了。
關於這方面的原理,可以參看
3)其他各類參數限制導致應用能力被約束,尤其以數據庫為甚
比如應用連接Oracle數據庫服務器的JDBC連接數太少,數據庫的process太少等等,導致應用在等待數據庫。如果單從數據庫來講,以Oracle為例,可以看看AWR的top等待事件。
比如logswitch等待時間長,可能需要調整redo日志組數和日志大小
比如索引等待時間長,可能需要調整為索引分區
比如rego日志sync等待時間長,可能需要調整存儲的能力。
4)應用邏輯設計問題
邏輯設計復雜,流轉過程長,導致不能很好的並發利用資源。
可以類比CPU流水原理,CPU設計為什么設置多級流水,而不是一級流水把一個指令執行完。
(二) CPU利用率居高不下
主機資源使用繁忙,到底是因應用需要做優化處理還是確實物理資源不足導致?
1. CPU資源不足,首先可以考慮優化。優化首先考慮技術層面優化
2. 如果技術優化無果,則進入業務優化。更改業務流程,業務處理方式。例如:
a) 實時檢查,改為定期檢查
b) 每秒鍾檢查一次,改為每分鍾檢查一次
c) 實時清算改為定時清算
3. 如果業務優化仍然無果,則需要加資源,甚至從總體上更改架構。畢竟任何CPU、任何服務器、任何系統都是有業務上限的。
CPU利用率居高不下的原因:
1. 絕大多數情況是應用寫的爛
算法差,或者無意的應用調用,觸發了內核函數占用CPU高。
這里所說的應用包括中間件、數據庫(比如SQL寫的差,沒做變量綁定(硬解析),索引設置不合理,數據庫物理設計不合理等等)。
2. 參數類 系統參數(比如緩存什么情況下往硬盤刷,設置不得當,刷的頻率太快) 編譯參數(各種優化選項,以及各種依賴關系) 數據庫參數(比如可以共享游標去節省CPU消耗,但卻沒有做) 中間件參數(比如GC策略)
AIX 關鍵業務系統CPU使用率高居不下,但是未對業務系統造成影響,如何進一步具體分析?
如果在貴單位認定的標准線以內,比如,CPU%不超過70即認為可以接受,不處理也沒關系。
1)有些應用可能已經優化到極致了。接下來考慮的是擴容、容量規划,必要時調整架構(分布式,大數據)。容量規划可以采用以下的步驟:
收集性能,、容量和事件數據(服務器統計數據,網絡統計數據,存儲統計數據,業務統計數據)
分析服務器性能和業務需求
性能趨勢分析,判斷未來需求
關聯數據,對性能和容量進行深入分析
提供“what-if”分析,識別未知的瓶頸
考慮虛擬化技術、優化成本、 供應和需求
生成報表提供更好的決策支持
2)如果不考慮擴容,僅考慮優化
采用nmon、topas、tprof,curt等工具分析什么進程、線程、函數占用了CPU,或者CPU在等待什么事件,進行深入分解和分析
(三) 如何應對CPU使用率毛刺問題?
毛刺不可怕,OS的CPU調度也不一定那么完美
首先需要判斷毛刺是1)周期性的,或者2)雜亂無章的,或者3)偶爾的突起。
1. 周期性的毛刺
列舉幾種可能的原因:
第一:發送到該服務器的業務量本身有周期性的增大。
第二:某個進程/任務周期性占用。如果是周期性監控進程占用CPU,問問監控系統的開發人員,咨詢監控軟件時候時間點發起監控、內部發起了什么操作或命令,這些操作是否可以優化。
第三:定期的鎖導致業務量在鎖時期積壓,鎖釋放后沖高
2. 雜亂無章的毛刺
第一:發送到該服務器的吞吐量本身有是高低不一的。
第二:讀取隊列的算法有問題,讀取不均勻
第三: OS調度問題
3. 偶發的毛刺
可以采用腳本或代碼抓取當CPU出現毛刺時的調用棧(CoreDump、tprof、truss等)。
也很有可能是某應用程序、系統程序或操作系統的bug
(四) 偶爾異常
有沒有好的方法監控異常占用CPU的進程?
這里采用的方法和“CPU偶發的毛刺”采用的方法一樣,采用腳本或代碼抓取當CPU出現毛刺時的進程和調用棧(nmon、ps、CoreDump、tprof、truss等方法)。
3
診斷工具
(一) CPU分析
vmstat, iostat, ps, sar, gprof/prof/tprof,time/timex, netpmon, locktrace,emstat,alstat,topas,trace, trcrpt,curt,splat,truss,procstack 等
(二) CPU優化
procmon,larstat,mpstat,cpupstat,nice/renice,schedo,bindprocessor,chdev,setpri等
(三) 實例
可以參考社區“系統性能測試”專欄中的幾篇文章(http://www.aixchina.net/Column/detail/id/9)
性能指標之資源指標-CPU-誰占用了CPU-進程級
性能指標之資源指標-CPU-誰占用了CPU-函數級-tProf
性能指標之資源指標-CPU-誰占用了CPU-函數級-curt
性能指標之資源指標-CPU-誰占用了CPU-函數級-truss
性能指標之資源指標-CPU-誰占用了CPU-函數級-CoreDump
(四) 收集CPU信息數據時需要注意一些什么?
需避免對業務運行造成影響。收集數據越全面的工具,消耗越多的資源(CPU、磁盤IO、存儲空間)。最好在業務量低的時候收集,除非你的問題是在業務量高的時候才出現。
收集時間要短,如果1分鍾的數據夠用,就只搜集1分鍾。像trace這樣的收集工具是每個邏輯CPU都分別搜集,如果你的幾十個CPU上跑的進程都差不多,可以少搜集一些CPU。
4
虛擬化相關
(一) PowerVM環境下的CPU監控和分析與物理機環境有哪些差異?
首先:利用率的概念不同。
虛擬化環境下CPU利用率相對於EC(標稱計算能力)來說,可以超過100%。
相對於VP(虛擬CPU)來說,永遠是<=100%。
相對於運行時獲得的物理CPU來說,永遠是<=100%。
CPU利用率的統計方法:

第二:虛擬化環境關注的參數更多,這些參數會對性能產生巨大的影響
虛擬化環境需同時關注以下參數:
CPU核數
標稱計算能力(Entitled Capacity,簡稱EC)
虛擬CPU(Virtual CPU,簡稱VP)
邏輯CPU個數(Logical CPU)
SMT
有上限/無上限(Capped/Uncapped)
型號/時鍾頻率
處理器折疊(Processor Folding)
運行時物理CPU(Physical CPU)
可以參考:
(二) 開發的應用在CPU核數一樣的虛擬服務器上性能表現出較大的差異
1、用的是什么虛擬服務器?VMware還是PowerVM的?還是其他的平台?
2、假如是VMware,用的是ESX/vSphere還是VMware Workstation,二者架構不同,性能不同,PC上的VMware Workstation不是裸金屬模式,性能不好。
3、虛擬機上看到的核數,可能不是真正的核數。比如說VMware上,看到的2個core,其實是x86 CPU的一個core中的一個超線程。
如果這個x86 CPU一個core是兩個線程,那么虛擬機中的兩個core只相當於物理的一個core。當然,這是能夠完全搶占的情況下。如果沒有完全搶占,那就更小了。
如果是PowerVM的虛擬機,操作系統看到的核數是VP(虛擬CPU),至於這個LPAR運行時候,能得到多少物理CPU以及這些物理CPU的親和性,可能差異很大。
PowerVM上CPU的概念可以參考:
性能指標之資源指標 CPU配置參數對性能的影響
(三) 虛擬化下CPU核數超分配有沒有最佳實踐
問題:在虛擬化的環境下,一般可以超分配CPU核數。一般會有一個臨界值。過了這個值CPU性能就大幅下滑。我們如何找這個值,有沒有什么最佳實踐?
所謂的“最佳實踐”其實是廠商給出通用值,具體到你的單位頭上,並不一定是最佳的。世界上沒有所謂的通用的最佳。就好比,兩地三中心、異地雙活之類的設計方案,沒有什么最佳實踐,每個企業都有根據自己的特點來設計。
回到你的問題,如果你的系統追求最短的響應時間(核心交易系統),VP和EC的比值越小越好。如果,追求最大瞬時CPU獲得,設置大一些更好,最大可以是10,適用於平時沒有什么業務量的非核心系統。
(四) EC高低似乎對業務響應時間沒什么影響,為什么?
問題1:

解答1:
這個是需要運氣的。
是否做上下文切換,取決於進程是不是每次被調用到同一個VP上,VP是不是每次被調用到同一個物理CPU上。
如果你的資源池,資源比較充足,那么hypervisor按照親和性調度,你的VP每次得到的物理CPU是一樣的,所以響應時間不受影響
反之,資源緊張,多個LPAR爭搶,親和性大打折扣,響應時間就起伏很大。
親和性的數值,可以通過下面方式查詢
Nmon的BBBP sheet
命令行Mpstat –d
問題2:
"那么如果要看運氣的話,物理資源多少才算閑置,總利用率多少需要開始關注CPU親和度了,需要開始着手處理此類問題了"
解答2:
首先要理解親和度的概念,是CPU是否能從cache1、2、3里面讀到數據。舉個例子,有1000個進程跑在一個CPU上,但都是不怎么干活的進程,一會兒進程A上來占用,一會進程B上來占用,但總體CPU利用率並不高,但每個進程上來后都要有自己的進程上下文。可能此時cache1、2、3根本緩存不了這么多上下文。結果就是大量的上下文切換。
因此不會有一個絕對的指標,說物理資源多少才開始關注CPU親和度。
針對 “物理機的整體CPU利用率究竟達到多少時,需要考慮擴大LPAR的EC”
是否擴大LPAR的EC,主要考慮的是你的業務需求是否能夠得到滿足(例如,響應時間是否滿足要求,吞吐量是否跟得上),而不是主要考慮物理機的整體CPU利用率。
CPU各核之間負載不均衡
1、nginx、redis之類的軟中斷引起的負載不均衡,通過設置CPU親和性來調整 記錄一個多核CPU負載不均衡問題
