Grafana
什么是Grafana?
Grafana使用Prometheus数据源官方文档
Grafana是一款功能强大的开源监控数据分析和可视化套件。它最初主要用于显示和监控Graphite指标数据,但随着时间的推移,其功能和应用范围得到了极大的扩展。Grafana的核心功能在于对基础设施和应用数据分析的时间序列数据进行可视化分析,使用户能够更直观地理解和分析数据。可以理解为一种前端展示
特点:
- 展示方式:快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中具有丰富的仪表盘插件,比如热图、折线图、图表等多种展示方式;
- 数据源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB等;
- 通知提醒:以可视方式定义最重要指标的警报规则,Grafana将不断计算并发送通知,在数据达到阈值时通过Slack、PagerDuty等获得通知;
- 混合展示:在同一图表中混合使用不同的数据源,可以基于每个查询指定数据源,甚至自定义数据源;
- 注释:使用来自不同数据源的丰富事件注释图表,将鼠标悬停在事件上会显示完整的事件元数据和标记;
- 过滤器:Ad-hoc过滤器允许动态创建新的键/值过滤器,这些过滤器会自动应用于使用该数据源的所有查询。
Grafana视图模板
Prometheus
Prometheus实战
- Retrieval:负责在活跃的target主机上抓取监控指标数据
- Storage:存储主要是把采集到的数据存储到磁盘中
- PromQL:是Prometheus提供的查询语言模块。
- Prometheus Server:用于收集和存储时间序列数据
- pushgateway:各个目标主机可上报数据到pushgateway,然后prometheus server统一从pushgateway拉取数据。
!!!Prometheus 的指标值,并非 100% 准确!!!
可观测三角
在可观测的世界里,metrics(指标)、log(日志)、trace(调用链) 三足鼎立。有点类似分布式系统的CAP理论
- metrics(指标)好似运动手表:24小时采样心率,并在心率超限时告警;
- log(日志)好似详细体检:输出厚厚一沓严密、精确的权威报告;
- trace(调用链)好似血管灌注:哪段血管堵了,只需看灌注造影,一目了然。
Prometheus 所在的 metrics(指标) 领域,其目标是诊断整体健康状况,其手段通常是对原始数据先采样、再聚合,利用有限的信息,分析变化趋势;而并非像 log(日志)那样,翔实精确、事无巨细地,记录每一桩事件、每一条原始数据。
Prometheus监控数据要点
请求类数据
- 请求量 - 按接口统计
- 错误数 - 按接口统计
- 接口耗时 - P50(可选)、P90、P95、P99、MAX
- 访问第三方资源数据 - 请求量、错误数、接口耗时
资源类数据
- 线程使用数
- 队列长度——run: size()——PushPackage:>10
- 协程使用数量
- 进程句柄数
- 机器句柄数
- 机器CPU
- 机器内存使用数量
- ….
组件类数据
- redis访问数据 - 访问量、耗时(Pxx)
- Mysql访问数据
- MQ访问数据
- …
自定义数据
- 特殊业务流量上报
- CUPS
- 特殊(重点关注)错误码
- …
Prometheus的数据形式—时间序列
在Prometheus中,时间序列数据以时间戳为索引,以连续的数据样本构成的系列称为时间序列。1
2
3
4
5│ . . . . . . . . . . . . . . . . . node_cpu{cpu="cpu0",mode="idle"} 时间序列1
│ . . . . . . . . . . . . . . . . . node_cpu{cpu="cpu0",mode="system"} 时间序列2
│ . . . . . . . . . . . . . . . .. node_load1{} 时间序列3
v
----------------------------------- 时间 ----------------------------------------->
1 | <-------------------- 指标 ------------------><--- 时间戳 ---><- 样本值 -> |
在形式上,所有的指标(Metric)都通过如下格式标示:1
<metric name>{<label name>=<label value>, ...}
Prometheus做出的妥协
宁愿“脑补”,也不愿低效。
除了 metrics 领域自身的特性,Prometheus 毕竟处在一个条件有限的真实世界,它还要随时面临以下困难:
- 自身硬件有限:不敢拼命计算,不敢无限存储;
- 采样统计的局限性:稀稀拉拉、分布未知的样本;
- 分布式的局限性:丢数据的网络、不靠谱的对端;
……
Prometheus 需要在上述限制下,交出 not perfect、但是 good enough 的指标。于是就有了下述设计:
- 单次采样不重要,多次采样组成的时间序列才重要。所以,单次采样受阻,是可以无需重试、直接丢弃的。
- 单点数值不重要,多点数值汇聚的变化趋势才重要。所以,单点数值是可以“无中生有”、”脑补”估算的。
P50、P90、P95
P90 是一个统计术语,代表着第90百分位数(90th percentile)。在性能监控和服务质量评估中,P90 常用来衡量响应时间或延迟的指标。具体来说,P90 的含义是在所有测量值中,有 90% 的数据点小于或等于这个值,而只有 10% 的数据点大于这个值。
例如,如果一个网络服务的响应时间的 P90 是 200 毫秒,这意味着在所有的请求中,90% 的请求的响应时间都不会超过 200 毫秒,只有 10% 的请求的响应时间会超过这个数值。这是一个衡量系统在高负载下性能的重要指标,因为它可以告诉你绝大多数用户的体验如何。
Prometheus的range
选择 rate 的 range 时,到底在选择什么?
- rate[30s] 计算过去 30 秒内的平均速率。
- rate[1m] 计算过去 1 分钟内的平均速率。
- rate[5m] 计算过去 5 分钟内的平均速率。
为什么上面三幅图选择范围不同图形状况会大变?
假设我们系统的错误数长期为0,而在某时刻暴增100,那么上述三种时间范围窗口,意味着将这 100 均分到 30秒,还是 60 秒,还是300秒;那么答案也显而易见:分母越大,按秒平均后的增量则越平滑。
总结:
- 窗口小则更加敏感,能够捕捉到更短时间内的变化。这意味着如果有突发事件或者短期波动,它会在曲线上表现得更明显。
- 窗口大会更加平滑,因为它平均了更长时间内的数据。这样可以减少短期波动的影响,但也可能掩盖掉短时间内的突发事件。
案例分解
rate/increase
在使用 rate 或者 increase 观测 counter 类型的指标增量时,经常碰到以下问题:
- 每分钟新增的请求数,竟然是个小数?
- 不仅是个小数,还比真实增量更大?
Prometheus在没有踩中样本值做法是:naive 地假设所有样本点在该时间范围内是均匀分布的,然后按照这个均匀分布的线性规律,脑补估算出边界上的采样点。那么,补出来一些不准确的值,也就不足为奇了。
其中脑补这一操作,使用的就是线性外推算法:rate/increase[时间范围] 在计算该时间范围内的增量时,第一步要拿到该时间范围边界上(开始时刻和结束时刻)的样本点,相减得到差值。但是:在当前时间范围的边界,并不一定那么凑巧地有样本点存在。
分析:
计算一分钟之内,errors_total 值的增量,也即 increase(errors_total[1m])。要计算 [1m] 的时间范围/取样窗口内的 increase,在最理想的情况下,Prometheus 根本不想关心这个窗口内的其他数据,而只需从窗口左边界取第一个点,右边界取最后一个点,相减即可:
但是,能保证每次都能踩中自己上报的值吗?答案很显然不能
取窗口覆盖范围内的第一个点和最后一个点,计算斜率,并按照该斜率将直线延伸至窗口边界,无中生有地“脑补”出虚拟的两个“样本点”,即可相减计算 increase 了:
如上图:用绿圈圈所代表的“虚拟样本”相减,得到的 increase 1.3 不仅是个小数,还比实际值偏大,也就不足为奇了。
histogram
histogram是柱状图,有三种作用:
- 对每个采样点进行统计(并不是一段时间的统计),打到各个桶(bucket)中
- 对每个采样点值累计和(sum)
- 对采样点的次数累计和(count)
为什么histogram得到的值会不准?
先从茫茫多的原始数据中采样出样本点,放到各个 bucket(桶)里;然后 naive 地假设所有样本是均匀分布的,据此做线性插值,“无中生有”出所需的“样本点”。
分析:
模拟拟每秒产生一个新的 HTTP 请求耗时的观察值,然后计算其 P99。为了埋点生成 http_response_time_seconds 这一 histogram 指标,每秒钟暴露一个观察值:假设有 50% 的概率,样本值大小在 [0.1, 0.5) 范围内。有 50% 的概率,样本值大小在 [0.5, 1.0) 范围内。
这里故意对histogram划分成四个不合理的桶: <= 0.1、<=0.5、<=100、<=正无穷。它们在各个桶内的分布,大致示意如下:
如何计算P99:1
histogram_quantile(0.99, rate(http_response_time_seconds_bucket[5m]))
99% 分位 总数 100 = 第 99 号。第 99 号样本在 0.5~100 bucket 段的第 51 号 ~ 第 100 号样本当中,排行 49。
*Prometheus 只知道:
- 有 50 个样本落在 0.5~100 bucket 段。
- 排行第一和排行最末的的样本值之差最大可达 100-0.5(bucket 段的左右边界之差)。
- 目标样本在这个 bucket 段里排行 49。
但是它并不知道:
- 这个 bucket 段左右边界的差值 100 - 0.5 是否完全分布到了这 50 个样本头上。
- bucket 段内的差值是如何分布到这 50 个样本头上的。
保险起见,Prometheus又自动脑补bucket 段内的全额差值,被均匀、线性地,分到了所有样本头上。因为这样就又可以用线性插值的方式,来计算分位值了:
所求分位值 = bucket 段左边界值 + (bucket 段右边界值 - bucket 段左边界值) (目标样本在本 bucket 段的排行 / 本 bucket 段的样本总数)即:P99 = 0.5 + (100 - 0.5) (49/50) = 98.01
summary
用于记录某些东西的平均大小,可能是计算所需的时间或处理的文件大小,summary显示两个相关的信息:count(事件发生的次数)和 sum(所有事件的总大小)。
例如:
- 在客户端对于一段时间内(默认是10分钟)的每个采样点进行统计,并形成分位图。(如:正态分布一样,统计低于60分不及格的同学比例,统计低于80分的同学比例,统计低于95分的同学比例)
- 统计班上所有同学的总成绩(sum)
- 统计班上同学的考试总人数(count)
如果返回次数为 3 和总和 15,也就意味着 3 次计算总共需要 15s 来处理,平均每次计算需要花费 5s。下一个样本的次数为 10,总和为 113,那么平均值为 11.3,因为两组指标都记录有时间戳,所以我们可以使用摘要来构建一个图表,显示平均值的变化率
怎么选择histogram和summary?
如果需要聚合,或对将要观察的值的范围和分布有所了解,请选择histogram。无论值的范围和分布是什么,如果都需要准确的分位数,请选择summary。
PromQL