分析服务响应时间分布,如:均值、中位值、P95值、P99值等如何计算
平均值
我们考察一个服务器的性能,除了QPS数据外,还会考察响应时间,当服务器负载增高时,往往会伴随着响应时间的增长,但是这个值该如何度量,以精准的表现服务器当前之负载呢?
最常用的值为平均值,表示服务的平均响应时间,通过该值我们能够知道服务当前响应的所有请求耗时的平均值。 例如平均耗时为100ms,表示服务器当前请求的总耗时/请求总数量,通过该值,我们大体能知道服务运行情况。 但是对于具体有多少个请求的耗时比100ms要大,大多少,是200ms,还是500ms,还是1000ms,我们无从得知。 而且,平均值这个数据容易掩盖一些异常值问题,比如,我的财富加激昂的太阳财富的平均值也能过亿,所以,平均值这个数据项过于简单,提供的信息量太少。
那为什么我们通常采用平均值来衡量或者监控服务性能呢?
主要是由于该值容易计算。
中位值
如上所述,由于平均值不能反映数据分布及极端异常值的问题,可以考虑采用中位值来作为度量。
中位值如何计算?
我们假设某服务在1s内响应了100个请求,耗时为X1、X2 … X100,可以对这100个数按照从小到大的顺序进行排序,在排序后的列表的中间位置的值——即为中位值,假设为150ms。
那这个值,150ms,表示什么意思呢? 它表示,服务器响应的这100个请求里面有50个的请求耗时小于150ms,另有50个请求的耗时大于150ms。
如果,我们有一个服务qps为3万/s,经过计算响应耗时中位值为100ms,那么我们可以推断有1.5万个请求的耗时小于100ms,也就是说我们有一半的用户的响应耗时小于100ms,据此我们就可以评估服务响应性能是否可以满足业务要求。
但是,这个中位值还有另外一个问题,我们只知道还有一半的请求耗时大于100ms,具体是大多少,大200ms,还是500ms,我们无法得知。
P95值与P99值
由于中位值只能反映中位数的问题,不能反馈更多信息,例如,我想知道该服务80%的请求耗时在多少ms以内,这些问题需要额外的数据指标。
P95——响应耗时从小到大排列,顺序处于95%位置的值即为P95值。
还是采用上面那个例子,100个请求按照响应时间从小到大排列,位置为95的值,即为P95值。 我们假设该值为180ms,那这个值又表示什么意思呢?
意思是说,我们对95%的用户的响应耗时在180ms之内,只有5%的用户的响应耗时大于180ms,据此,我们掌握了更精确的服务响应耗时信息。
P99.9值
亚马逊经常采用P99.9值,也就是99.9%用户耗时作为指标,也就是1000个用户里面,999个用户的耗时上限,如果测量与优化该值,即可保证绝大多数用户的使用体验。 至于P99.99值,优化成本过高,而且服务响应由于网络波动、系统抖动等不能解决之情况,故暂不考虑该指标。
如何计算P分位值
如上说过平均值的计算方式,而P值需要将响应耗时从小到大排序,然后取得对应百分位之值。
如果服务qps较低,例如:100/秒,记录这100个耗时数据,然后排序,然后取得P分位值,倒不是难事。 而如果qps较高,例如:30万/秒,如果还是采用记录+排序的方式,可以预见需要消耗大量内存与计算资源。
有没有简单的计算方式呢?
可以采用直方图来进行计算,该计算方式虽不是完全准确值,但精度非常高,误差较小。
直方图需要界定两个直方之间的跨度,一般采用等分形式,例如对于耗时统计需求,我们可以假定一个耗时上界,然后等分,比如划分成100个区间,对于每个响应耗时落入对应的直方,如下图:
这样就避免了对全部数据进行排序,只需要根据各个直方中的数据数量,即可计算出95%位置位于哪个直方,然后在该直方内部采用插值方法,计算出P95值。
另外,考虑到数据分布特点,服务耗时异常数据应该只是少数,但是异常值跨度可能很大,大部分耗时数据均靠近正常值,如果直方统计采用等分形式,会导致大量数据堆积在一个直方中,如何解决这个问题?
可以采用非等分的跨度划分方式,例如采用指数形式划分,耗时越低的区间,跨度越小,精度约高。