本文主要會介紹性能評估的一些簡單概念以及性能壓測/性能瓶頸的識别方法和一些常見的優化方式。雖然内容很多,但是目的在于讓大家有個全局的認識;本文雖然深入度上面稍微欠缺,但是足以應對日常的性能分析。
為什麼大家覺得性能優化難?
很多人覺得性能優化難的原因,其實主要是不知道怎麼去做評估,主要表現在一下幾個方面
1、不知道性能是什麼?
2、不知性能的評估标準是什麼?
3、不知道影響性能的相關元素是什麼?
4、不知道性能問題的帶來的現象是什麼?
性能優化,必須知道的幾個概念
關于性能的幾個基礎概念就像一把刀,你需要知道他可以用來削水果,還可以用來殺人。
認知,決定了你能拿它幹什麼,決定了能否識别到本質。
性能調優,就是一條通過現象看本質的認知之路。
性能優化中必須知道的幾個概念諸如:
1、 響應時間(RT)
2、 吐出量(QPS/TPS)
3、 資源(CPU、線程等)
下面通過對這幾個概念的詳細剖析,進行講解。
QPS概念掃盲
概念QPS:Query Per Second
TPS:Transactions PerSecond
起源:資料庫系統中表述性能的重要名額。
現在:對于應用系統而言,現在QPS,TPS的概念有點混淆,泛指系統機關時間的處理能力。
這兩個概念是衡量性能很明确的名額,我們用它來泛指機關時間系統的處理能力。但是僅僅知道QPS/TPS的概念,就能做性能分析,性能調優了嗎?是哪些因素會影響QPS/TPS?
接下來我一層層來剖析:響應時間模型,線程模型,已經線程和資源之間的關系。
深入了解響應時間組成模型
很多人對響應時間的組成是不清晰,導緻不能很好的判斷,時間消耗在了什麼地方。明白時間消耗的節點是很重要的一件事。
不知道響應時間組成的優化就像是亂槍打鳥。需要明白時間消耗在什麼地方,是什麼原因造成的消耗。
不要認為隻有CPU消耗;更不要認為加CPU核數就可以解決問題。
通常是通過埋點的方式把代碼執行切分成一段一段的片段,擷取各個節點、各類節點的消耗,用于觀察性能情況,定位性能瓶頸點;鍊路上的埋點,可以配合監控系統統一來看,阿裡是自己實作了一個簡單的埋點類。
響應時間是程式(程序、線程)在資源(CPU)運作的一個展現。是以,資源和程式運作的載體會影響這個結果。下面深度了解JAVA的線程模型。
深入了解線程模型
程序/線程是程式運作的載體,是以深入了解線程的機制有助于幫助性能分析。請看下圖
左上的圖,是線程幾個狀态之間的扭轉。
左下的圖,是線程在鎖的争用時候的運作态。
右上的圖講linux中,java主程序、java線程/LWP輕量級程序和CPU排程,CPU綁定運作的模型:
1、線程/程序是作業系統排程的關鍵資源。
2、了解器運作機制有利于知道一個請求中的運算是消耗在什麼節點。CPU隻是一個點,其他資源也是會影響線程的執行。
3、多線程情況下,線程不一定是滿轉的,遇到共享資源争用的時候,會造成阻塞。
線程和CPU是程式運作的寶貴資源。資源不足會造成性能問題;資源富足優惠造成資源浪費。到底比對多少資源才是最優的呢?
下一步解釋最優線程數,如何最優化資源配比,了解資源之間的關系。
深度剖析最優線程數
最優線程數定義- 盡可能保持應用對資源的最大化使用。
- 當線程數較少的時,有壓力情況下,可能造成線程資源不足,請求需要等待線程釋放後才能處理。
- 當線程數較多的時,線程自身也是需要消耗記憶體資源的,導緻資源的浪費,同時,線程較多的時候對于線程的排程和争用也會影響性能。
如何确定或者使用盡量少的線程,就能讓目前的資源高效利用呢?
可能大家有個疑問:怎麼最優線程數,有毛用啊!我反正給他很多線程,這不就完事了嗎?比如最後線程是100,我給你200(好,你是牛人,你是有錢人,哈哈)
但是我認為:對資源使用情況的合理了解和分析,是很重要的,尤其是如果你是個老闆,你要關心錢用了多少吧,那些錢不該花吧!如果你是個技術人員,你要告訴你的老闆這些是啊,畢竟你是一個有追求的程式員(不然老闆就開了你。。。)
為了剖析最優線程數和資源之間的關系,下面我講一步步分解,讓大家了解。
深度了解瓶頸資源
為了了解瓶頸資源,假設一個業務場景:
下面通過對程式運作态通過圖表的方式是呈現出來,便于大家了解瓶頸資源、多資源情況下的線程排程。
以5ms作為一個時間幀。
第1個5ms如下
cpu同時可以運4個線程,是以請求11,21,31,41執行,其餘5個請求,等待CPU資源。
第2個5ms如下
cpu同時可以運4個線程,其餘5個請求,等待CPU資源。
第3個5ms如下
第4個5ms如下
第5個5ms如下
通過快照圖,我可以看到什麼?
一個多資源的程式中:
對資源的争用表現為對瓶頸資源的争用,性能情況會受制于瓶頸資源。瓶頸資源可以用水桶原理來解釋,如下圖。
基于上述對線程、瓶頸資源的梳理,我們很容易提煉出QPS的理論公式,大家可以看下面的公式,如果覺得燒腦,可以多看幾遍。
深入了解QPS公式
最優線程公式1、 最優線程數量=線程總時間/瓶頸資源時間 * 瓶頸資源并行數
2、 一個線程1S可以處理的請求數
3、 1000/線程總時間
QPS公式1:QPS =最優線程數量* 1000/線程總時間
QPS公式2:QPS=1000/瓶頸資源時間 * 瓶頸資源并行數
這個公式裡隐含了一些有趣的解釋,大家可以去揣摩下。
性能壓測:從了解瓶頸到如何識别瓶頸
前面講的都是理論,很多很多理論,下來大家可以花些時間了解。主要目的是讓大家對性能有個可量化的名額衡量,知道名額了,那麼下一步就是講如何獲得這些名額,如果通過這些名額發現問題。
接下來的章節,如何識别瓶頸資源,常用的方式是壓測,下面是壓測模型圖(沒有講怎麼使用jmeter壓測等)
壓測模型抽象性能壓測是有方法,有模式,有目标的。如何對壓測進行管理,如何創造壓力,如何準備被測系統,如何準備壓測資料,如何收集壓測資料,如何分析壓測資料。是要進行穩定壓測,還是要進行瓶頸壓測等等。
性能壓測是一件很專業的事情,對于壓測,了解壓測的組成環境是很重要的,有的時候,壓測的環境就是壓測瓶頸。
壓測環境組成
這裡講兩個環境:
1、壓力機環境:不要認為壓不上去了就是被測系統的問題,曾經也遇到過jmeter處理壓測響應資料的性能瓶頸,導緻一緻壓不上去。
2、依賴系統/資料的影響:舉個例子比如叢集部署後,線上A調用B應用,A是100台,B是1000台;但是線下性能實驗室A和B是1:1關系。1:1壓測出來的資料是否就是線上的資料呢,這裡是有一個問号的。
壓測需要注意的一些事項
- 了解環境
- 壓測環境和線上環境的不同
- 避免壓測環境的不同造成壓測結果的不可行
- 吞吐量和響應時間的取舍和平衡
- 确定合理的性能預期值
- 适可而止
- 不做過度的優化,在性能和其他因素(架構,可維護性)等的平衡
- 選取合适的壓測場景設計用例
- 天花闆
- 充分利用資源
- 不過度使用資源
從識别瓶頸到如何進行優化
内容可以見下圖
如何識别瓶頸?永遠也不會廢的方法,隔離法和替換法。當你覺得對哪一塊懷疑(CPU、IO、線程、壓力機、外圍系統)的時候,可以快速的使用這些方法識别。
比如你可以使用mock,擋闆,更換機器。
這兩個方法很簡單,比冥思苦想有用多了,是以性能優化,不要把自己逼瘋了。
優化手段,可以見圖中方式,性能優化有一定招式,但是結合具體場景後,有各種取舍,不要一味生搬硬套。
Q&A
Q1 什麼時候需要優化性能?需要提前考慮麼?
我認為性能的問題是一個技術人員、架構師骨子裡的東西(需要提前考慮);但是實施的步驟是根據你的業務場景、業務量、業務增量、系統目前的容量,系統的擴充性等問題來考慮(比如是否可以水準擴充應對等),不用做過渡的超前設計。
Q2 上圖中的N+1那個N指什麼?
N就是對CPU的核數,這裡隻是了解了很多人/或者網上提高的一些經驗值,這些經驗值有可能是在沒有考慮多資源的情況下的值,但是有可能你的系統就不是一個CPU密集運算性系統
Q3 比較感興趣耗時統計工具,是開源的麼?有移動端的統計工具麼?
耗時統計的這個東西,我覺得主要是看埋點。你用什麼東西埋點,對于阿裡體系也就是一個簡單的類。沒有那麼複雜;對于鍊路上的,我認為可以列印各個節點的達到時間,最後監控來看。
移動端的工具,我接觸很少,sorry。
Q4 測試性能的機器 怎麼選 有的說要高配,有的說要爛機器。
沒那麼多講究,不要聽很多大公司的忽悠,不要全聽咨詢師的,黑一把咨詢師。舉個例子,原來都說我們要用大型機,然後要用小型機,現在大家都用 pcserver。
關于作者
陳顯銘,從事研發工作七年,螞蟻金服技術專家,愛思考,愛黑人
中生代技術分享群微信公衆号