如何做好微服務容量規劃?
維護眾多服務需要巨大的努力,手動操作已不再可行。以微博的動態推送功能為例,僅遠程過程調用(RPC)服務就接近40種。這些服務接口的性能和需求各不相同,一些接口雖然處理請求量大,但響應迅速,稱為輕量級接口;另一些接口處理的請求量較少,但響應時間較長,稱為重量級接口。
例如,在微博的動態推送中,計數接口的響應時間極短,僅需2至3毫秒,而動態獲取接口的響應時間則超過200毫秒。服務集群的規模差別明顯,擴展所需的服務器數量也大相徑庭。比如微博的A/B測試服務可能只需增加幾臺服務器即可應對增長,而動態推送服務可能需要增加上百臺服務器。另外,在擴展服務時,還需注意服務間的相互依賴性,確保所有依賴的服務都有足夠的處理能力。例如,微博的動態推送業務在擴展時不僅依賴于現有的服務器容量,還依賴于用戶關系和卡片服務的容量是否充足。
容量規劃系統的作用是根據各個微服務部署集群的最大容量和線上實際運行的負荷,來決定各個微服務是否需要彈性擴縮容,以及需要擴縮容多少臺機器。
容量評估一般集群的容量評估都是通過線上實際壓測來確定的,那么該如何進行線上壓測呢?都需要注意哪些關鍵點呢?
1. 選擇合適的壓測指標
在進行性能測試時,我們通常關注兩大類指標:系統指標和服務指標。系統指標包括CPU使用率、內存使用量、磁盤I/O和網絡帶寬等,而服務指標涉及到接口的平均響應時間、P999延遲(即99.9%的請求在這個時間內得到響應)和錯誤率。然而,這些指標并不總是能夠準確地反映系統在負載下的表現。例如,低CPU使用率不一定意味著接口響應時間就是健康的,而高CPU使用率也不一定導致接口性能不佳。同樣,服務指標如平均響應時間也可能掩蓋實際問題,比如在壓測中即使只有少量的請求響應時間延長,平均值也可能看起來不變。
基于我的經驗,除了監控上述指標之外,還應該檢查接口的慢請求比例,即超過特定響應時間閾值的請求占總請求的比例。例如,在對微博的動態推送接口進行壓測時,我們關注的是響應時間超過1秒的請求的比例,如果這一比例超過1%,則應停止壓測。這是因為如果99%的請求能在1秒內完成,用戶體驗通常不會受到太大影響。對大多數在線服務而言,保持慢請求比例在1%以下是服務質量的基本標準,因此這個指標可以作為一個有效的壓測性能指標。
2. 壓測獲取單機的最大容量
要確定一個服務器集群能處理的最大負載,我們首先需要知道單個服務器能承受的最大負載,然后這個數值乘以集群中服務器的總數。獲取單臺服務器最大負載的方法通常分為兩種:單機壓測和集群壓測。單機壓測可以通過復現實際流量的日志或復制實時流量到一個服務器上來進行。而集群壓測則是通過逐步減少集群中的服務器數量來增加單個服務器上的負載,從而測試每臺服務器的極限。
根據我的經驗,集群壓測更為可靠,因為它利用真實的線上流量進行測試,可以得到更準確的單臺服務器負載極限。但是,集群壓測可能會對實際運行中的服務造成影響,因此通常在流量較低的時段進行。此外,為了便于及時應對可能出現的問題,這類壓測一般安排在工作日進行。
在集群壓測中,我們會監控慢請求的比例,并在這一比例達到1%時停止壓測。此時,我們可以用停止壓測時的每臺服務器平均每秒查詢數(QPS)作為單臺服務器的最大容量指標。但是,僅僅使用QPS作為衡量標準并不總是準確的,因為它不一定能完全反映服務器的真實負載情況。例如,如果有兩個服務器,其QPS相同,但一個主要處理響應時間低于100毫秒的請求,另一個處理的請求響應時間都超過50毫秒,則后者對服務器的負載更重。即使兩臺服務器的QPS都是100,處理更多慢請求的服務器可能已經無法處理更高的QPS,而另一臺則可能還有余力。
圖片
因此,一種更為精確的方法來衡量單個服務器的容量是通過對不同響應時間段的請求賦予加權值,這種方法稱為區間加權。每個時間段的請求都有不同的權重,反映了它們對服務器負載的實際影響:更長的響應時間獲得更高的權重。例如,響應時間在0到10毫秒之間的請求權重為1,10到50毫秒為2,50到100毫秒為4,100到200毫秒為8,200到500毫秒為16,超過500毫秒的為32。根據這種加權方法,前述兩種情況下服務器的容量可以計算為第一種情況的請求(8個請求×權重1)+(50個請求×權重2)+(30個請求×權重4)+(10個請求×權重8)+(2個請求×權重16)等于340,而第二種情況下的計算為(2個請求×權重2)+(10個請求×權重4)+(50個請求×權重8)+(20個請求×權重16)+(8個請求×權重32)等于1020。通過這種方式,我們可以得到在壓測終止時刻,經過區間加權計算得到的單個服務器的最大容量。
3. 實時獲取集群的運行負荷
為了估算集群的總負荷,首先,我們需要通過壓力測試確定單個服務器的最大處理能力。將這個數值乘以集群中服務器的數量,就能得出整個集群的最大處理能力。接下來,為了判斷是否需要對集群進行擴展,關鍵在于準確估算當前集群的實際運行負載。
由于直接計算每個服務器的負載并將它們加總的方法在大規模集群(例如超過千臺服務器)中效率低下,因此采用了一種更高效的方法。這種方法涉及收集每臺服務器在不同響應時間區間的請求數量,然后將這些數據發送到一個中心處理點進行整合。在這個中心點,對同一集群中不同服務器在各個響應時間區間的請求數據進行匯總,從而得到整個集群在各個時間區間的請求分布情況。利用這些分布數據并結合區間加權的計算方法,就能有效估算出集群的整體運行負荷。
調度決策
在容量評估過程中,了解集群的最大容量與實際運行負載是關鍵。這兩個數據點可用于形成有效的調度策略。類似于監控水庫的水位,這種策略涉及實時監測集群的資源利用情況。如果集群的負載超過了預設的警戒線,類似于水庫的水位過高,就需要采取措施來減輕負擔,比如通過擴容或重新分配資源。
相反,如果負載低于某個閾值,像是水庫水位過低,那么可以選擇減少資源,以優化成本和效率。這樣的方法確保集群負載始終保持在理想狀態,既不過載也不閑置。通過將集群的最大容量與實際運行負荷的比值作為“水位線”,可以有效地實時監控和調整集群的運行狀態。
圖片
在調度決策時候,就可以根據水位線來做決定。你可以看到下面圖中劃分了兩條線,一條是安全線,一條是致命線。當集群的水位線位于致命線以下時,就需要立即擴容,在擴容一定數量的機器后,水位線回到安全線以上并保持一段時間后,就可以進行縮容了。
圖片
- 擴容策略:在決定增加多少機器時,通常根據集群現有規模的比例來進行。例如,可以選擇每次擴展總機器數的30%,然后重新評估集群的負載情況。這種按比例擴容的方法適用于各種規模的集群,能確保擴容后的負載仍然保持在安全范圍內。
- 縮容策略:當集群的負載在安全水平上維持一定時間后,可以考慮縮容以節約成本。縮容的時機和頻率可根據業務特點決定。例如,如果業務流量通常在一小時內回落,可以在負載維持在安全線以上一個小時后開始縮容??s容過程中采取逐步減少的方式,如每隔五分鐘按照一定比例(例如10%、30%、50%)逐步減少機器,以避免因過快縮容導致負載突然增加。總結:容量評估方面,首先要通過壓測獲取集群的最大容量,并實時采集服務調用的數據以獲取集群的實時運行負荷,這樣就可以獲取集群的實時水位線。而調度決策方面,主要是通過水位線與致命線和安全線對比來決定什么時候該擴縮容。而擴縮容的數量也是有講究的,擴容的機器數一般按照集群機器數量的比例來,而縮容一般采取逐步縮容的方式以免縮容太快導致反復擴容。