【精选】99分位、95分位计算 实时分位数的统计方法 | 您所在的位置:网站首页 › 百分位数等化方法怎么算 › 【精选】99分位、95分位计算 实时分位数的统计方法 |
之前做的一个项目上线有一段时间了,但一直也没有来得及做统计分析(峰值、平均QPS、……)。最近刚好又被问到了这个事情,所以抽空学习了解一下部分监控指标的概念和含义,方便后续自己做统计分析。 一、分位数 1、概念分位数(Quantile),TP=Top Percentile,即对一批数值型数据进行排序之后,排在p%位置的数值大小,是数据分析中非常重要的统计指标之一。常用的分位数包括:80分位数,90分位数,99分位数等。 然而,在实时计算(流式计算)场景中,由于无法在有限的时间内对海量数据进行全局的排序,给实时分位数的计算带来一定的技术挑战。 TP50、TP90和TP99等指标常用于系统性能监控场景,指高于50%、90%、99%等百分线的情况。 2、计算/统计方法TP50:指在一个时间段内(如5分钟),统计该方法每次调用所消耗的时间,并将这些时间按从小到大的顺序进行排序,取第50%的那个值作为TP50的值;配置此监控指标对应的报警阀值后,需要保证在这个时间段内该方法所有调用的消耗时间至少有50%的值要小于此阀值,否则系统将会报警。 举例:假设现在有4次请求耗时分别为: 10s 1000s 100s 2s 计算TP百分线的方法就是: 1、先按升序排列 [2s, 10s, 100s, 1000s]; 2、找到你需要用做统计的最后一个条目(向高取整)对应的数值,比如:TP50就是第 ceil(4*0.5)=2 个,即 10s ;TP90就是第 ceil(4*0.9)=4 个,即 1000s 。 3、为什么用百分位数而不是平均数?自个想,你都来了你还问我这? 这有说的明白的:Why averages suck and percentiles are great | Dynatrace news 参考distributed system - What do we mean by "top percentile" or TP based latency? - Stack Overflow 第95个百分位(95th percentile)是什么概念? - 知乎 tp90和tp99是指什么性能指标,求大神解释下? - 知乎 二、如何计算或统计这个分位数呢 1、TDigest计算分位数TDigest是一个简单,快速,精确度高,可并行化的近似百分位算法,被Spark,ES,Kylin等系统使用。TDigest的核心思想是通过聚类的方法将离散的数据点聚集为多个不同的质心,在通过线性差值法计算分位数,线性差值法是最简单的插值算法。 如上图所示,将离散的数据点(图中无色的数据点)聚类为多个不同的质心(图中彩色的数据点),其中每个质心周围的数据点数决定了该质心所占的权重(图中质心的大小),最后通过对所有的质心进行排序,就可以使用线性插值法求取对应的分位数,其中数据点与质心的距离和权重关系如下图所示。 特别地,在每个TDigest创建时有一个重要的compression参数,主要用于在计算的精确度与空间复杂度之间做权衡: 当compression参数设置越大时,聚类得到的质心越多,则差分法求取的分位数精确度越高 当compression参数设置越大时,TDigest数据结构占用的存储空间越大,则分位数计算的空间复杂度越高 随着数据量的增大,compression的取值应适当增大,能够有效提高计算的准确率 2、架构模型1) 从上游业务方读取需要统计分位数的原始数据 2) 根据业务方需求的分组规则,按分组聚合为TDigest数据结构,将聚合结果存入Redis中,或与Redis中已存在对应的数据进行合并,以获取准确的计算结果 3) 从TDigest结构中获取分位数的计算结果,并向上返回 3、问题在实际的业务需求中,我们可能需要按照不同的时间、查询维度等信息检索统计的分位数。但是,已经计算好的两个分位数结果是无法进行聚合操作的。 解决:按所有查询维度进行提前聚合计算的解决方案,即针对每一种可能出现的查询维度组合都提前计算分位数并存储,在查询过程中直接检索对应查询维度的聚合计算结果 (感觉有点。。。) 三、Prometheus重点来了 Prometheus是一个监控平台,通过抓取目标上和metric相关的HTTP endpoint,收集被监控目标的metrics。本文会指导你怎么安装、配置prometheus,并通过prometheus监控资源。你将会下载、安装、运行prometheus;下载、安装exporter or tools(输出主机或服务的时间序列数据)。我们介绍的第一个exporter是Node Exporter(输出主机级别的metrics,比如CPU、内存、磁盘)。 1、官方架构图prometheus存储的是时序数据,即按相同时序(相同名称和标签),以时间维度存储连续的数据的集合。 时序(time series)是由名字(Metric)以及一组key/value标签定义的,具有相同的名字以及标签属于相同时序。 metric名字:表示metric的功能,如http_request_total。时序的名字由 ASCII 字符,数字,下划线,以及冒号组成,它必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*, 其名字应该具有语义化,一般表示一个可以度量的指标,例如 http_requests_total, 可以表示 http 请求的总数。 标签:使同一个时间序列有了不同维度的识别。例如 httprequests_total{method=”Get”} 表示所有 http 请求中的 Get 请求。当 method=”post” 时,则为新的一个 metric。标签中的键由 ASCII 字符,数字,以及下划线组成,且必须满足正则表达式 [a-zA-Z:][a-zA-Z0-9_:]*。 样本:按照某个时序以时间维度采集的数据,称之为样本。实际的时间序列,每个序列包括一个float64的值和一个毫秒级的时间戳 一个 float64 值 一个毫秒级的 unix 时间戳 格式:Prometheus时序格式与OpenTSDB相似: {=, ...} {=,…},例如:http_requests_total{method="POST",endpoint="/api/tracks"}Metric类型: Counter: 一种累加的metric,如请求的个数,结束的任务数,出现的错误数等Gauge: 常规的metric,如温度,可任意加减。其为瞬时的,与时间没有关系的,可以任意变化的数据。Histogram: 柱状图,用于观察结果采样,分组及统计,如:请求持续时间,响应大小。其主要用于表示一段时间内对数据的采样,并能够对其指定区间及总数进行统计。根据统计区间计算Summary: 类似Histogram,用于表示一段时间内数据采样结果,其直接存储quantile数据,而不是根据统计区间计算出来的。不需要计算,直接存储结果 3、PromQLPromQL (Prometheus Query Language) 是 Prometheus 自己开发的数据查询 DSL 语言。 查询结果类型: 瞬时数据 (Instant vector): 包含一组时序,每个时序只有一个点,例如:http_requests_total 区间数据 (Range vector): 包含一组时序,每个时序有多个点,例如:http_requests_total[5m] 纯量数据 (Scalar): 纯量只有一个数字,没有时序,例如:count(http_requests_total) 4、查询条件通过名称及标签进行查询,如http_requests_total等价于{name="http_requests_total"} 查询level="info"的event: logback_events_total{level="info"} 查询条件支持正则匹配: http_requests_total{code!="200"} // 表示查询 code 不为 "200" 的数据 http_requests_total{code=~"2.."} // 表示查询 code 为 "2xx" 的数据 http_requests_total{code!~"2.."} // 表示查询 code 不为 "2xx" 的数据内置函数: 如将浮点数转换为整数: floor(avg(http_requests_total{code="200"})) ceil(avg(http_requests_total{code="200"})) 查看每秒数据 : rate(http_requests_total[5m])基本查询: 查询当前所有数据 logback_events_total 模糊查询: level="inxx" logback_events_total{level=~"in.."} logback_events_total{level=~"in.*"} 比较查询: value>0 logback_events_total > 0 范围查询: 过去5分钟数据 logback_events_total[5m] 时间范围单位有以下: s: 秒m: 分钟h: 小时d: 天w: 周y: 年在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准。 如果想查询5分钏前的瞬时样本数据,则需要使用位移操作,关键字:offset, 其要紧跟在选择器{}后面。如: sum(http_requests_total{method="GET"} offset 5m) rate(http_requests_total[5m] offset 1w) 5、聚合、统计高级查询 count查询: count(logback_events_total)sum查询: sum(logback_events_total)svg查询:topk: 如查询2的值:topk(2, logback_events_total)irate: 如查询过去5分钟的平均值: irate( logback_events_total[5m]) 6、配置启动时,可以加载运行参数-config.file指定配置文件, 默认为prometheus.yml: 在该配置文件中可以指定各种属性,其结构体定义如下: type Config struct { GlobalConfig GlobalConfig `yaml:"global"` AlertingConfig AlertingConfig `yaml:"alerting,omitempty"` RuleFiles []string `yaml:"rule_files,omitempty"` ScrapeConfigs []*ScrapeConfig `yaml:"scrape_configs,omitempty"` RemoteWriteConfigs []*RemoteWriteConfig `yaml:"remote_write,omitempty"` RemoteReadConfigs []*RemoteReadConfig `yaml:"remote_read,omitempty"` // Catches all undefined fields and must be empty after parsing. XXX map[string]interface{} `yaml:",inline"` // original is the input from which the config was parsed. original string }全局配置 global: 主要有四个属性 scrape_interval: 拉取 targets 的默认时间间隔。 scrape_timeout: 拉取一个 target 的超时时间。 evaluation_interval: 执行 rules 的时间间隔。 external_labels: 额外的属性,会添加到拉取的数据并存到数据库中。 7、Exporter负责数据汇报的程序统一叫Exporter,不同的Exporter负责不同的业务。其统一命名格式:xx_exporter 举个例子,如果你有一台服务器,你想要获取它运行时候的参数,比如当前的CPU负载、系统负载、内存消耗、硬盘使用量、网络IO等等,那么你就可以在服务器上运行一个node_exporter,它能帮你把这些参数收集好,并且暴露出一个HTTP接口以便你访问查询。 已有exporter 8、clientlib 9、pull模式prometheus.yml内容如下: global: scrape_interval: 15s evaluation_interval: 15s rule_files: # - "first.rules" # - "second.rules" scrape_configs: - job_name: 'spring' metrics_path: '/actuator/prometheus' static_configs: - targets: ['自己本机ip:8080']启动prometheus docker: docker run --name prom --hostname prom -p 9090:9090 -v /Users/liukun/config/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus启动以后,我们运行http://localhost:9090 可以访问Prometheus。 10、Pushgateway使用Pushgateway原因: Prometheus采用pull模式,可能由于不在一个子网或防火墙导致无法直接拉取各target数据 需要将不同数据汇总后,再由Prometheus统一收集 其缺点: pushgateway宕机影响范围会更大。 prometheus拉取状态up只针对pushgateway,无法做到对每个节点有效。 pushgateway可以持久化推送给它的所有监控数据 docker run -d \ --name=pg \ -p 9091:9091 \ prom/pushgateway在其启动后,通过访问:http://localhost:9091就可以查看到其界面 pushgateway默认是不持久化数据的,如果需要,则可以通过启动时加入参数 : docker run -d -p9091:9091 prom/pushgateway "-persistence.file=push_file"向pushgateway推送数据: 1. 使用Client SDK 2. 直接使用API 使用API向Pushgateway推数据 如下为直接使用API进行数据推送: echo "some_metric 3.14" | curl --data-binary @- http://localhost:9091/metrics/job/some_job发送更复杂的数据,可以加上instance,表示来源位置: cat |
CopyRight 2018-2019 实验室设备网 版权所有 |