系統設計目標:如何提升系統性能?
高并發系統設計的核心目標是要保證系統在處理大量并發請求時,能夠保持高性能、高可用性以及良好的可擴展性。這三個方面相互關聯,共同支撐著系統能夠應對不斷增加的流量和需求。具體來說:
- 性能:系統需要在高并發場景下保持低延遲的響應時間,確保用戶體驗。比如,面對每秒一萬次請求的情況下,系統需要保證響應時間在毫秒級,而非秒級,否則用戶體驗會大打折扣。
- 可用性:高并發系統需要能夠保持長時間的穩定運行。即使面對突發的大量流量,系統也應當能夠保證服務不中斷。例如,一些大型電商平臺在“雙十一”期間,雖然流量激增,但仍需確保全天候無故障運行。
- 可擴展性:高并發系統必須能夠應對峰值流量的挑戰,這需要系統具備良好的擴展能力。通常,面對流量的波動,特別是突發流量時,系統應該能夠在短時間內擴容,并且不影響正常運行。
在進入如何提升系統性能之前,我們可以從一些常見的技術手段著手,例如:
- 負載均衡:通過分發請求到多個服務器,避免單點瓶頸,提高系統的并發處理能力。
- 緩存:減少對數據庫和其他后端服務的依賴,通過緩存熱點數據,減輕系統壓力。
- 異步處理:對于耗時操作,通過異步任務來處理,不阻塞主流程。
- 數據庫優化:通過讀寫分離、分庫分表等策略優化數據庫訪問效率。
這些方法是提高性能的基礎,接下來可以深入探討如何根據具體情況進一步優化。
性能優化原則
在進行性能優化時,確實需要遵循一些基本原則,尤其是面對高并發系統設計的復雜性。下面總結了幾個優化的關鍵點,幫助我們有效地提升系統性能:
1. 問題導向
盲目優化是效率低下的。優化應當基于實際的性能瓶頸,而不是做無目的的優化。例如,如果系統中某個組件沒有遇到性能問題,就不需要對其進行優化。相反,我們應當關注最影響性能的部分,優先解決這些問題。這通常可以通過 性能監控 和 分析工具 來幫助識別瓶頸。
2. “八二原則”
性能優化要遵循“八二原則”——20%的優化措施解決80%的問題。在實際工作中,我們經常會發現,只有少數幾個性能瓶頸點在占據了大部分系統資源。因此,找到這些瓶頸并對其進行優化,可以帶來最明顯的性能提升。
3. 數據支撐
性能優化不僅要有明確的目標,還要通過數據來驗證效果。你可以利用 性能測試工具(如 JMeter、LoadRunner、或者自己的自定義監控工具)來進行基準測試,評估響應時間、吞吐量、并發請求數等關鍵指標。優化之后,及時記錄和比較優化前后的數據變化,從而確保優化是有效的。
4. 持續優化
性能優化是一個不斷迭代的過程。隨著系統的業務邏輯變得越來越復雜,新的瓶頸可能會不斷出現。因此,持續的性能測試和優化是非常重要的。在設計高并發系統時,我們不可能一次性解決所有問題,而是要持續監控、分析并逐步優化。
性能的度量指標
性能優化中,性能度量標準至關重要,因為它幫助我們明確系統的實際性能狀態,并能用來衡量優化措施的效果。只有通過合理的度量指標,我們才能清晰地知道性能瓶頸在哪里,哪些優化是有效的。單次響應時間是基礎指標,但它并不足夠全面,因此需要通過一些統計方法來進一步分析數據。
常見的性能度量特征值
- 平均值
平均響應時間是最常見的性能度量指標,它通過將所有請求的響應時間加總并除以總請求數來計算。雖然平均值在一定程度上能反映系統性能,但它對極端值(如偶爾的慢請求)非常不敏感。正如你提到的,在大多數請求響應時間為1ms的情況下,單個100ms的慢請求也不會對平均值產生很大影響,因此可能導致性能問題被低估。
優點:簡單易懂,易于計算。
缺點:對偶發的慢請求不敏感,可能掩蓋性能問題。 - 最大值
最大響應時間記錄了所有請求中最慢的一次響應。它可以告訴我們最糟糕的性能情況,但它對偶發的異常情況(如一次長時間的網絡延遲)非常敏感,可能會嚴重扭曲性能的實際水平。
優點:可以展示最差的性能情況。
缺點:非常敏感,可能不代表大部分請求的實際性能。 - 分位值
分位值是性能度量中更為精確的標準,常見的有 90分位、95分位 和 99分位。以90分位為例,它表示在所有請求中,90%的請求響應時間小于等于某個值,剩余10%的請求響應時間則更長。分位值通過消除極端的慢請求影響,能夠更準確地反映大多數請求的性能情況。
圖片
在我來看,分位值是最適合作為時間段內,響應時間統計值來使用的,在實際工作中也應用最多。除此之外,平均值也可以作為一個參考值來使用。我在上面提到,脫離了并發來談性能是沒有意義的,我們通常使用吞吐量或者響應時間來度量并發和流量,使用吞吐量的情況會更多一些。但是你要知道,這兩個指標是呈倒數關系的。這很好理解,響應時間 1s 時,吞吐量是每秒 1 次,響應時間縮短到 10ms,那么吞吐量就上升到每秒 100 次。所以,一般我們度量性能時都會同時兼顧吞吐量和響應時間,比如我們設立性能優化的目標時通常會這樣表述:在每秒 1 萬次的請求量下,響應時間 99 分位值在 10ms 以下。
高并發下的性能優化
假如說,你現在有一個系統,這個系統中處理核心只有一個,執行的任務的響應時間都在 10ms,它的吞吐量是在每秒 100 次。那么我們如何來優化性能從而提高系統的并發能力呢?主要有兩種思路:一種是提高系統的處理核心數,另一種是減少單次任務的響應時間。
1. 提高系統的處理核心數
提高系統的處理核心數就是增加系統的并行處理能力,這個思路是優化性能最簡單的途徑。
通過增加并行進程提高吞吐量
以我們之前的例子為基礎,假設你將系統的處理核心數增加為兩個,并且增加一個進程,使得這兩個進程分別在不同的核心上運行。這樣,從理論上講,你的系統吞吐量可以增加一倍。
在這種情況下,吞吐量和響應時間不再呈倒數關系,而是遵循以下公式:
吞吐量 = 并發進程數 / 響應時間
這意味著,增加并發進程數有助于提高系統的吞吐量,然而,響應時間并不一定按比例縮短。
阿姆達爾定律 (Amdahl’s Law)
計算機領域的 阿姆達爾定律(Amdahl’s Law)由吉恩·阿姆達爾在 1967 年提出,用于描述并發進程數與響應時間之間的關系。它主要說明了并行計算的加速比,也就是并行化之后效率提升的情況。
阿姆達爾定律的公式為:
其中:
- W_s 表示任務中的串行計算量
- W_p 表示任務中的并行計算量
- s 表示并行進程數
從這個公式,我們可以推導出另一個公式:
其中:
- s 表示并行進程數
- p 表示任務中并行部分的占比
結論
- 當 p = 1 時,也就是任務完全可以并行化時,加速比與并行進程數 s 成正比,系統的性能可以隨之線性提升。
- 當 p = 0 時,任務完全是串行的,無法并行化,加速比為 1,系統性能無法提升。
- 當 s 趨近于無窮大時,加速比趨近于 1 / (1 - p),這意味著即使增加無限多個處理核心,提升的效果也會受到 p(并行部分的占比)的限制。
特別注意
- 當 p = 1 時,任務完全并行化時,理論上加速比是無限的,這也是并行化帶來的最大效益。
- 當 p 遠小于 1,即任務中大部分是串行計算時,即便增加大量并行進程,性能提升也會受到極大限制。
簡化結論
盡管阿姆達爾定律的公式推導有些復雜,實際工作中我們通常只需要記住以下結論:
- 完全并行的任務能夠無限加速(p = 1)。
- 任務的串行部分(p < 1)會限制系統的并行化效果。
我們似乎找到了解決問題的銀彈,是不是無限制地增加處理核心數就能無限制地提升性能,從而提升系統處理高并發的能力呢?很遺憾,隨著并發進程數的增加,并行的任務對于系統資源的爭搶也會愈發嚴重。在某一個臨界點上繼續增加并發進程數,反而會造成系統性能的下降,這就是性能測試中的拐點模型。
圖片
從圖中可以看出,當并發用戶數處于輕壓力區時,響應時間保持平穩,吞吐量與并發用戶數呈線性關系。而當并發用戶數進入重壓力區時,系統資源接近極限,吞吐量開始下降,響應時間略有上升。進一步增加壓力時,系統進入拐點區,超負荷狀態下吞吐量下降,響應時間急劇上升。因此,評估系統性能時,我們通常通過壓力測試來找到系統的“拐點”,以了解系統的承載能力,并定位瓶頸,進行持續優化。
接下來,我們來看看優化性能的另一種方式:減少單次任務的響應時間。
2. 減少單次任務響應時間
想要減少任務的響應時間,首先需要判斷系統是 CPU 密集型還是 IO 密集型的,因為不同類型的系統優化方法不同。
CPU 密集型系統
CPU 密集型系統主要處理大量的 CPU 運算。在這種情況下,選用更高效的算法或減少運算次數是提升性能的重要手段。例如,如果系統的主要任務是計算 Hash 值,選擇更高性能的 Hash 算法能夠顯著提升系統性能。
發現這類問題的主要方法是使用 Profile 工具,如 Linux 的 perf 或 eBPF,來找出消耗 CPU 時間最多的方法或模塊。
IO 密集型系統
IO 密集型系統的大部分操作都在等待 IO 完成,這里的 IO 指的是磁盤 IO 和網絡 IO。大多數系統,如數據庫系統、緩存系統、Web 系統,都是 IO 密集型系統。其性能瓶頸可能出現在系統內部,也可能在依賴的其他系統。
發現 IO 性能瓶頸的手段主要有兩類:
- 使用工具,Linux 提供了豐富的工具集,如網絡協議棧、網卡、磁盤、文件系統、內存等工具,能幫助排查問題。
- 通過監控來發現性能問題,監控可以對任務的每個步驟做分時統計,從而找出哪些步驟消耗了更多時間。
優化方案
優化方案因問題不同而異。例如,如果是數據庫訪問慢,可能需要檢查是否有鎖表、全表掃描、索引是否合適、JOIN 操作是否優化、是否需要加緩存等;如果是網絡問題,則需要檢查網絡參數、抓包分析是否有大量超時重傳、網卡是否有丟包等。