服務響應時間的衡量指標
P90 P95 P99
分析服務響應時間分布,如均值,中位值,P95值,P99值等計算
平均值
- 考察伺服器性能,除了QPS數據外,還要查看響應時間,如何精準的表現伺服器當前之負載
- 常用的值為:平均值(服務的平均響應時間)
- 例如平均耗時為100ms,表示伺服器當前
請求的總耗時/請求總數量
,通過該值,我們大體能知道服務運行情況
- 例如平均耗時為100ms,表示伺服器當前
P50
- 表示請求中的中位數
P90
- 響應耗時從小到大排列,順序處於90%位置的值即為P90值
P95
- 響應耗時從小到大排列,順序處於95%位置的值即為P95值
- 100個請求按照響應時間從小到大排列,位置為95的值,即為P95值。 我們假設該值為180ms,那這個值又表示什麼意思呢?
- 意思是說,我們對95%的用戶的響應耗時在180ms之內,只有5%的用戶的響應耗時大於180ms,據此,我們掌握了更精確的服務響應耗時資訊。
P99.9
- 亞馬遜經常採用P99.9值,也就是99.9%用戶耗時作為指標,
- 也就是1000個用戶裡面,999個用戶的耗時上限,如果測量與優化該值,即可保證絕大多數用戶的使用體驗。
- 至於P99.99值,優化成本過高,而且服務響應由於網路波動、系統抖動等不能解決之情況,故暫不考慮該指標。
如何計算P分位值
-
可以採用直方圖來進行計算,該計算方式雖不是完全準確值,但精度非常高,誤差較小。
-
直方圖需要界定兩個直方之間的跨度,一般採用等分形式
-
例如對於耗時統計需求,我們可以假定一個耗時上界,然後等分,比如劃分成100個區間,對於每個響應耗時落入對應的直方
-
此外,考慮到數據分布特點,服務耗時異常數據應該只是少數,但是異常值跨度可能很大,大部分耗時數據均靠近正常值,如果採用桶等分的形式,可能會導致大量數據堆積在一個桶內中,又如何解決這個問題?
-
其實可以採用非等分的跨度劃分方式,例如採用指數形式劃分,耗時越低的區間,跨度越小,精度約高。
-
此外,話可以採用美團點評的實時檢控官系統cat的桶跨度劃分方式
public static int computeDuration(int duration) { if (duration < 1) { return 1; } else if (duration < 20) { return duration; } else if (duration < 200) { return duration - duration % 5; } else if (duration < 500) { return duration - duration % 20; } else if (duration < 2000) { return duration - duration % 50; } else if (duration < 20000) { return duration - duration % 500; } else if (duration < 1000000) { return duration - duration % 10000; } else { int dk = 524288; if (duration > 3600 * 1000) { dk = 3600 * 1000; } else { while (dk < duration) { dk <<= 1; } } return dk; } }
-
百分位數值在互聯網系統中有很大的意義。通過對百分位數值的監控與優化,我們可以將更多的用戶納入我們的監控體系中,讓我們的服務能夠對絕對大多數的用戶提供更好的體驗!在一些錯誤率、異常率上面我們也可以使用百分位數來進行系統可用性是否達到要求,甚至在一些新的產品特性或者AB測試上也可以用來統計分析用戶對其的反響,以此來衡量該特性是否真正對用戶有幫助……
衡量指標的定義
RPS:衡量伺服器的吞吐能力,每秒處理器處理的請求數,是伺服器並發處理能力的量化描述
- 也稱 TPS 每秒處理的事務數
- RPS = 總請求數 / 請求的總耗時
QPS:每秒查詢數,每秒能夠響應的查詢次數,QPS業績最大吞吐能力
Avg:衡量伺服器答題處理情況,平均處理每個請求耗時 - Avg = 請求總耗時 / 總請求數
P90:單個請求響應耗時從小到大排列,順序處於90%位置的值即為P90 值。
P95:單個請求響應耗時從小到大排列,順序處於95%位置的值即為P95 值。
P99:單個請求響應耗時從小到大排列,順序處於99%位置的值即為P99 值。
Python計算各項指標
import numpy as np
a = np.array([1,2,3,4,5])
p_90 = np.percentile(a, 90)
p_95 = np.percentile(a, 95)
p_99 = np.percentile(a, 99)
avg = np.average(a)
min = np.min(a)
max = np.max(a)
print("p90 = {} \np95={} \np99={} \navg={} \nmin={} \nmax={}".format(p_90,p_95,p_99,avg,min,max))