分析服务响应时间分布,如:均值、中位值、P95值、P99值等如何计算。

平均值

我们考察一个服务器的性能,除了QPS数据外,还会考察响应时间,当服务器负载增高时,往往会伴随着响应时间的增长,但是这个值该如何度量,以精准的表现服务器当前之负载呢?

最常用的值为平均值,表示服务的平均响应时间,通过该值我们能够知道服务当前响应的所有请求耗时的平均值。

平均值计算公式:

1
服务器当前请求的总耗时/请求总数量

但是平均值有一个弊端,通过该值是可以大体能知道服务运行情况,但是无法得知细节情况。

例如平均耗时为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值

由于中位值只能反映中位数的问题,不能反馈更多信息,例如,我想知道该服务80%的请求耗时在多少ms以内,这些问题需要额外的数据指标。

P95:响应耗时从小到大排列,顺序处于95%位置的值即为P95值。

还是采用上面那个例子,100个请求按照响应时间从小到大排列,位置为95的值,即为P95值。 我们假设该值为180ms,那这个值又表示什么意思呢?

意思是说,我们对95%的用户的响应耗时在180ms之内,只有5%的用户的响应耗时大于180ms,据此,我们掌握了更精确的服务响应耗时信息。

P99值

经过上面的定义,P99也就是:响应耗时从小到大排列,顺序处于99%位置的值即为P99值。

亚马逊经常采用P99.9值,也就是99.9%用户耗时作为指标,也就是1000个用户里面,999个用户的耗时上限,如果测量与优化该值,即可保证绝大多数用户的使用体验。 至于P99.99值,优化成本过高,而且服务响应由于网络波动、系统抖动等不能解决之情况,故暂不考虑该指标。

如何计算P分位值

如上说过平均值的计算方式,而P值需要将响应耗时从小到大排序,然后取得对应百分位之值。

如果服务qps较低,例如:100/秒,记录这100个耗时数据,然后排序,然后取得P分位值,倒不是难事。 而如果qps较高,例如:30万/秒,如果还是采用记录+排序的方式,可以预见需要消耗大量内存与计算资源。

有没有简单的计算方式呢?

可以采用直方图来进行计算,该计算方式虽不是完全准确值,但精度非常高,误差较小。

直方图需要界定两个直方之间的跨度,一般采用等分形式,例如对于耗时统计需求,我们可以假定一个耗时上界,然后等分,比如划分成100个区间,对于每个响应耗时落入对应的直方,如下图:

这样就避免了对全部数据进行排序,只需要根据各个直方中的数据数量,即可计算出95%位置位于哪个直方,然后在该直方内部采用插值方法,计算出P95值。

另外,考虑到数据分布特点,服务耗时异常数据应该只是少数,但是异常值跨度可能很大,大部分耗时数据均靠近正常值,如果直方统计采用等分形式,会导致大量数据堆积在一个直方中,如何解决这个问题?

可以采用非等分的跨度划分方式,例如采用指数形式划分,耗时越低的区间,跨度越小,精度越高。