突破性能CI

什麼是性能CI

性能CI可簡單定義爲CI(Continuous Integration)集成性能測試用例。主要用於監控系統運算速度、存儲容量或網絡I/O是否滿足系統設置指標,而非發現故障。

性能測試通常包括:負載測試(Load Test)、壓力測試(Stress Test)、容量測試(Volume Test)、峯值測試(Spike Test)等非功能型測試。


性能CI的價值

一方面,Donald Knuth告訴我們“過早的優化是萬惡之源”,

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. - Computer Programming as an Art(1974) P671.

當然,我並無意挑起性能狂人與設計大師們的戰爭,但凡有些性能優化經驗的同學定能理解其中要義,過早的優化至少會帶來如下問題:

  • 忽略整體設計
  • 陷入局部優化
  • 破壞可讀性
  • 增加偶發複雜度

另一方面,對於遺留系統,發現性能問題往往爲時已晚。會帶來:

  • 定位成本高
  • 優化難度大
  • 波及影響多
  • 測試成本高

所以,我們期望做到:

  1. 開發人員專注於設計、編碼
  2. 提交代碼出現性能問題及時告警
  3. 可視化性能數據,並可鏈接到劣化代碼
  4. 提供定位信息協助分析

性能CI面臨的主要問題

  1. 性能用例的有效性不高

    簡言之,監控的場景不能包含性能劣化路徑。表現爲內場表現良好,外場表現糟糕;局部性能良好,系統性能糟糕。

  2. 性能用例部署、執行時間較長

    CI要求更早、更快的反饋。性能測試受制於物理環境、儀表資源、採樣週期等限制,通常自動化部署困難,用例執行時間長。

  3. 性能測試數據的穩定性

    判決讓人信服的前提是準確。由於不同的構建機器、不同的部署環境、不同的用例配置、不同組件間的干擾、性能指示器數據的波動等原因,性能測試數據出很大波動性,導致難以判決劣化是由於合入代碼還是波動所致。

  4. 自動化準確識別劣化點

    劣化閾值設置過大可能漏掉某些劣化點,設置過小可能產生誤報,準確識別劣化點困難。另外,由於諸多約束,很多判斷需要人爲干預,完全自動化較困難。

解決思路與方法

通過對性能CI面臨主要問題的分析,核心要解決有效性、高效性、穩定性、擴展性四方面的問題。

  1. 提高性能測試用例的有效性
  • 業務價值驅動,識別劣化路徑

    “程序的性能特質傾向高度的非直覺性”,性能優化靠猜是極其不告譜的。性能劣化路徑的識別亦如此,我們需要根據系統在真實部署環境的業務場景,選擇用例,確定用例部署優先級。

  • 解耦系統內不同組件間的干擾

    在一定程度上,可以對複雜系統的各個組件的性能分開驗證,可以考慮犧牲一些不關注組件的真實性,換取關注組件的穩定性。

  • 自動準確識別性能劣化點並分級告警

    自動準確的識別劣化點,是判定性能CI是否有效的關鍵指標。需要動態找到某個閾值作爲置信區間,我們可以參考異常檢測方法。常見的異常檢測方法有:極值分析,概率統計建模,線性迴歸模型,信息論模型,高維孤立點檢測等。下面介紹一種實測中比較有效實時告警的方法:

    Mean(N) ± SD(N),其中N表示樣本容量,Mean表示平均值,SD表示標準差。樣本容量選取過去一段時間產生的樣本,不能選取過去的所有樣本,否則置信區間無法收斂。

    分級告警是指可以定義實時告警、觸頂告警等不同級別告警。

    • 實時告警:以過去一段時間的樣本作爲實時告警模型的輸入並生成置信區間,當前數據超出該區間則告警。
    • 觸頂告警:以某個初始基準值作爲參考,設置可以容忍的最大劣化/優化閾值並生成置信區間,當前數據超出該區間則告警。觸頂告警一般用於實時告警無法捕捉到的、緩慢增加的劣化的場景,觸頂告警一旦觸發,預示需要啓動專項優化了。
  1. 提高性能測試用例的高效性
  • 測試用例分級部署

    分級部署是指將性能測試用例分級部署在單元測試,集成測試,系統測試等不同階段。用例間相互補充,可以更高效的利用測試資源,減少用例執行時間。

  • 測試用例並行部署

    如果測試用例部署環境充足,考慮並行部署用例,可以大大縮短用例執行時間,簡化用例部署場景。

  • 不同構建按不同粒度監控

    如果做不到用戶每次提交在給定的時間窗內給出執行結果,可以考慮將多次提交打包成一次構建執行,出現告警後打包提交逐單回退驗證(需要部署鏡像環境用於回退單驗證)。

  • 尋求慢速性能指標的替代指標

    如果在用性能指示器的採樣週期較長,在不影響穩定性的前提下,考慮尋求其他更快速性能指標進行替換。性能指標包括:CPU Utilization,Latency,IPC(Or CPI),Cycles,Instructions,CacheMiss.

  1. 提高性能測試數據的穩定性
  • 部分模擬環境代替真實物理環境

    真實物理環境相對於模擬環境更脆弱,更不易控制,在分級部署原則的指導下,對於不關注組件,可是考慮使用模擬環境代替真實物理環境。

  • 增加系統內其他組件的穩定性

    複雜系統是由多個組件組成,系統性能表現爲它們共同作用的結果,通過打樁等手段,提高不關注組件的穩定性,有利於提高被監控組件的穩定性。

  • 增大樣本容量(冗餘)

    冗餘是提高穩定性最常用的方法,挑戰在於在樣本量增加情況下,如何不增加執行時間。推薦使用Latency,IPC等指標代替CPU使用率。

  • 多維度樣本參照(相關性)

    具有相關性、不同維度的性能數據相互參照,提高判定的準確性。

  • 尋求波動性能指標替代指標

    系統性越強的性能指示器(例如CPU使用率)波動性越大,考慮使用一些可被拆分、組合的指示器(例如函數時延,Cycles等)替代。

  1. 提高性能用例的擴展性
  • 抽象出框架與API接口
    良好的擴展性基於對操作的抽象、良好的分層、穩定的API接口,性能CI對日誌數據的操作可以抽象爲數據採集、數據處理、數據持久化、數據可視化四層,每層定義清晰的API接口,性能用例僅需要新增配置即可。

  • 工作環境與測試環境分離
    工作環境負責及時反饋性能劣化點,鏡像環境負責對劣化點優化的驗證,二者並行工作



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章