背景
在大多数情况下人们都倾向于使用某些量化指标的平均值,例如CPU的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统API调用的平均响应时间为例:如果大多数API请求都维持在100ms的响应时间范围内,而个别请求的响应时间需要5s,那么就会导致某些WEB页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。
为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在0~10ms之间的请求数有多少而10~20ms之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram和Summary都是为了能够解决这样问题的存在,通过Histogram和Summary类型的监控指标,我们可以快速了解监控样本的分布情况。
百分位数(quantile)
Prometheus中称为quantile,其实叫percentile更准确。百分位数是指小于某个特定数值的采样点达到一定的百分比。例如,假设0.9-quantile的值为120,意思就是所有的采样值中,小于120的采样值的数量占总体采样值的90%。相应的,假设0.5-quantile的值为x,那么意思就是指小于x的采样值占总体的50%,所以0.5-quantile也指中值(median)。
相对于简单的平均值来说,百分位数更丰富,更能反应出真实的用户体验。常用的百分位数为0.5-quantile,0.9-quantile以及0.99-quantile。这也是Prometheus默认的设置。
注:这只是Prometheus中Summary目前版本的默认设置,在版本v0.10中,这些默认值会废弃,意味着默认的Summary将没有quantile设置。
Histogram也是Prometheus在client端支持的四种metrics类型之一。与Summary类似,每定义一个Histogram类型的metrics,实际也会生成几个metrics。例如,
Histogram会产生下面6类metrics。后面4个可以用于计算quantile值。
http_request_duration_millisecond_count
http_request_duration_millisecond_sum
http_request_duration_millisecond_bucket
http_request_duration_millisecond_bucket
Histogram主要是设置不同的bucket,采用值分别落入不同的bucket。例如上面第一个bucket就是响应时间小于10ms的采样点的数量,第二个bucket就是响应时间小于50ms的采样点的数量,依此类推。
注意后面的采样点是包含前面的采用点的,例如xxx_bucket的值为30,而xxx_bucket的值为120,那么意味着这120个采用点中,有30个是小于10ms的,其余90个采样点的响应时间是介于10ms和50ms之间的。
注意+Inf是最高bucket的上限值,所以xxx_bucket是所有采样点的数量,是Prometheus自动增加的一个bucket。
计算quantile值直接用函数histogram_quantile即可,例如下面是计算0.9-quantile的值,
histogram_quantile(0.9, rate(http_request_duration_milliseconds_bucket[10m]))
上面会针对每种label组合计算出一个出一个0.9-quantile值,也就是对每个"path"会计算出一个值。如果要针对所有path计算出一个汇总的值,则用如下语句,
histogram_quantile(0.9, sum(rate(http_request_duration_milliseconds_bucket[10m])) by (le))
使用Histogram计算quantile值,最大的问题就是:因为Histogram采用了线性插值法,所以如果bucket设置不合理,那么最后计算出的值可能偏差比较大。例如在前面的例子中,假设0.9-quantile的结果在10ms~50ms之间,但是表达式必须返回一个具体的值,这时就采用线性插值法得出36ms。显然这种方法计算出的值可能会有误差,而且范围越大,例如10ms ~ 500ms,那么误差也会越大。
Summary和Histogram对比
Summary不能对quantile值进行aggregation操作,而Histogram则可以;所以如果针对多实例的场景计算quantile,只能使用Histogram;
如果histogram的bucket设置不合理,则最后误差可能会很大;所以如果需要相对精确的结果,而且是单实例场景,那么就使用Summary;
Summary对quantile的计算是在client端通过第三方库perks做的;而Histogram对quantile的计算则是server端完成的;
Summary计算出的quantile值是基于进程开始运行至今的所有采样值计算出来的;而Histogram则是基于最近的一段时间的采样值计算出来的,更符合monitoring系统的本质。
引用:https://cloud.tencent.com/developer/news/319419