Prometheus 架构
Prometheus 由开源编程语言 Go 编写,并且是在 Apache 2.0 许可证下授权的。它孵化于云原生计算基金会。
Prometheus 通过抓取或拉取应用程序中暴露的时间序列数据来工作。时间序列数据通常由应用程序本身通过客户端库或 exporter 的代理来作为 HTTP 端点暴露。目前已经存在很多的 exporter 和客户端库,支持多种编程语言,框架和开源应用程序,如 Apache Web 服务器和 MySQL 数据库等。
Prometheus 还有一个推送网关(push gateway),可用于接收少量数据,例如,来自无法拉取的目标数据(如临时作业或者防火墙后面的目标)。
指标收集
- 端点(endpoint):Prometheus 称其可以抓取的指标来源为端点,端点通常对应单个进程,主机,服务或者应用程序。
- 目标(target):为了抓取端点数据,Prometheus 定义了名为目标的配置。这是执行抓取所需的信息。例如,如何进行连接,要应用哪些元数据,连接需要哪些身份验证,或者定义抓取将如何执行的其他信息。
- 作业(job):一组目标被称为作业(job)。作业通常是具有相同角色的目标组,例如,负载均衡器后面的 Apache 服务器集群,它们实际上是一组相似的进程。
生成的时间序列数据被收集并存储在 Prometheus 服务器本地,也可以设置从服务器发送数据到外部存储器或者其他时间序列数据库。
服务发现
可以通过多种方式来处理要监控的资源的发现,包括:
- 用户提供的静态资源列表;
- 基于文件的发现。例如,使用配置管理工具生成在 Prometheus 中可以自动更新的资源列表;
- 自动发现。例如,查询 Consul 等数据存储,在 Amazon 或 Google 中运行实例,或使用 DNS SRV 记录来生成资源列表。
什么是指标
指标
是软件或硬件组件属性的度量。为了使指标有价值,我们会跟踪其状态,通常记录一段时间内的数据点。这些数据点称为观察点
(observation),观察点通常包括值,时间戳,有时也涵盖描述观察点的一系列属性(如源或标签)。观察的集合称为时间序列
。
我们通常以固定的时间间隔收集数据,该时间间隔被称为颗粒度
(granularity)或者分辨率
(resolution),取值可以从1秒到5分钟,甚至到60分钟或者更长。正确的选择指标的颗粒度至关重要,若选择得太粗糙,则很容易错过某些细节。例如,以5分钟为间隔对 CPU 或内存使用情况进行采样,几乎不可能识别出数据中的异常情况。另外,如果颗粒度过于精细,则需要存储和分析大量数据。
时间序列数据是这些观察点按时间序列排列的的集合。时间序列指标通常被可视化为二位图形,其中 X 轴是时间,Y 轴是具体的数据值。通常,你会在 Y 轴上看到多个数据值 – 例如,来自主机的多个 CPU 使用率值,或者成功和失败的事物。
指标类型
测量型(Gauge)
第一种指标类型是测量型(gauge),这种类型是上下增减的数字,本质上是特定度量的快照。常见的监控指标如 CPU,内存和磁盘使用率等都属于这个类型。对于业务指标来说,指标可能是网站上的客户端数量。
计数型(Counter)
第二种类型是计数型(counter),这种类型是随着时间增加而不会减少的数字。虽然它们永远不会减少,但有时可以将其充值为零并再次开始递增。应用程序和基础设施的计数型示例包括系统正常运行时间,设备收发包的字节数或登录次数。业务方面的示例可能是一个月内的销售数量或应用程序收到的订单数量。
计数型指标的一个优势在于它们可以让你计算变化率。每个观察到的数值都是在一个时刻: t,你可以使用 t+1 处的值减去 t 处的值,以获得两个值之间的变化率。通过了解两个值之间的变化率,可以理解许多有用的信息。例如登录次数指标,你可以通过计算变化率来查看每秒的登录次数,这有助于确定网站这段时间的受欢迎程度。
直方图(Histogram)
直方图是对观察点进行采样的指标类型,可以展现数据集的频率分布。将数据分组在一起并以这样的方式显示,这个被称为 分箱
(binning) 的过程可以直观地查看数值得相对大小。统计每个观察点并将其放入不同的桶中,这样可以产生多个指标:每个桶一个,加上所有值得总和以及计数。
直方图可以很好地展现时间序列数据,尤其适用于数据的可视化(如应用程序延迟等)。
摘要型(Summary)
还有一种指标类型,称为 摘要型
(summary),类似于直方图,但它还会计算百分位数。更多信息参考 Histograms and Summaries
指标摘要
通常来说,单个指标对我们价值很小,往往需要联合并可视化多个指标,这其中需要应用一些数学变换。例如,我们可能会将统计函数应用于指标或指标组,一些可能应用的常见函数包括:
- 计数: 计算特定时间间隔内的观察点数;
- 求和: 将特定时间间隔内所有观察点的值累计相加;
- 平均值: 提供特定时间间隔内所有值得平均值;
- 中间数: 数值的几何中点,正好 50% 的数值位于它前面,而另外 50% 则位于它后面;
- 百分位数: 度量占总数特定百分比的观察点的值;
- 标准差: 显示指标分布中与平均值的标准差,这可以测量出数据集的差异程度。标准差为 0 表示数据都等于平均值,较高的标准差意味着数据分布的范围很广;
- 变化率: 显示时间序列中数据之间的变化程度。
指标聚合
除了上述的指标摘要外,可能还希望看到来自多个源的指标的聚合视图,例如所有应用程序服务器的磁盘空间使用情况。指标聚合最典型的样式就是在一张图上显示多个指标,这有助于你识别环境的发展趋势。例如,负载均衡服务器中的间歇性故障可能导致多个服务器的 Web 流量下降,这通常比通过查看每个单独的指标更容易发现。
从上图中看一看到 30 天内多个主机的磁盘使用情况,它为我们提供了一种快速确定某主机的当前状态(和变化率)的方法.
最终,你会发现单一指标和聚合指标的组合可以提供最佳的监控视图:前者可以深入到某个特定问题,后者可以查看更高阶的状态。
监控方法
我们将在指标和指标聚合之上结合使用多种监控方法,以帮助加强监控。我们将结合以下两种监控方法:
- Brendan Gregg 的 USE(Utilization,Saturation 和 Error)方法,侧重于主机级别的监控。链接
- Google 的四个黄金指标,专注于应用程序级别的监控。
监控方法提供的指导原则可以让你缩小范围并专注于所收集的海量时间序列中的特定指标。上述两个监控框架,一个侧重于主机级性能,一个侧重于应用程序级性能,结合使用可以获得一个相当全面的环境视图,帮助你解决任何问题。
USE 方法
USE 是使用率(Utilization),饱和度(Saturation)和错误(Error)的缩写,该方法是由 Netflix 的内核和性能功能师 Brendan Gregg 开发的。USE 方法建议创建服务器分析清单,以便快速识别问题。可以利用从你的环境中收集的数据,对照清单来确定常见的性能问题。
USE 方法可以概括为:针对每个资源,检查使用率,饱和度和错误。该方法对于监控那些受高使用率或饱和度的性能问题影响的资源来说是最有效的。
让我们快速查看每个术语的定义以帮助理解:
- 资源: 系统的一个组件。在 Gregg 对模型的定义中,它是一个传统意义上的物理服务器组件,如 CPU,磁盘等,但许多人也将软件资源包含在定义中;
- 使用率: 资源忙于工作的平均时间。它通常用随时变化的百分比表示;
- 饱和度: 资源排队工作的指标,无法再处理额外的工作。通常用队列长度表示;
- 错误: 资源错误事件的计数。
我们将这些定义结合起来创建一份资源清单,并采用一种方法来监控每个要素:使用率,饱和度和错误。它们是如何起作用的呢?假设我们有一个严重的性能问题,想深入了解以便诊断。参考我们的清单并检查每个被监控组件的各个要素。在这个示例中,我们将从 CPU 开始:
- CPU 使用率随时间的百分比;
- CPU 饱和度,等待 CPU 的进程数;
- 错误,通常对 CPU 资源不太有影响;
然后是内存:
- 内存使用率随时间的百分比;
- 内存饱和度,通过监控 swap 测量;
- 错误,通常不太关键,但也可以捕获。
其他组件以此类推,直到我们找到了问题的瓶颈或信号。
可以查看 Brendan Gregg 提供的 Linux 系统的参考示例清单
Google 的四个黄金指标
Google 的四个黄金指标来自 Google 的 SRE 手册,它们采用与 USE 类似的方法,指定要监控的一系列通用指标类型。此类方法中的指标类型主要关注的不是系统级的时间序列数据,更多的是针对应用程序或面向用户的部分:
- 延迟: 服务请求所花费的时间,需要区分成功请求和失败请求。例如,失败请求可能会以非常低的延迟返回错误结果;
- 流量: 针对系统,例如每秒 HTTP 请求数,或者是数据库系统的事物;
- 错误: 请求失败的速率,要么是 HTTP 500 错误等显式错误,要么是返回错误内容或无效内容等隐式错误,或者基于策略原因导致的失败 – 例如,强制要求响应时间超过 30ms 的请求视为错误。
- 饱和度: 应用程序有多
满
,或者受限的资源,如内存或 IO。这还包括即将饱和的部分,例如正在快速填充的磁盘。
黄金指标使用起来很简单,依次选择对应的高阶指标,然后为它们设置警报。如果其中一个指标出现问题,那么警报就会响起,然后你可以去诊断或解决问题。
聚合和警报
服务器还可以查询和聚合时间序列数据,并创建规则来记录常用的查询和聚合。这允许你从现有时间序列中创建新的时间序列,例如,计算变化率和比率,或者产生类似求和等聚合。这样就不必重新创建常用的聚合,例如用于调试,并且预计算可能比每次需要时运行查询性能更好。
Prometheus还可以定义警报规则。这些是为系统配置的在满足条件时触发警报的标准,例如,资 源时间序列开始显示异常的CPU使用率。Prometheus服务器没有内置警报工具,而是将警报从 Prometheus 服务器推送到名为 Alertmanager (警报管理器)的单独服务器。Alertmanager 可以管理、整合和分发各种警报到不同目的地——例如,它可以在发出警报时发送电子邮件,并能够防止重复发送。
查询数据
Prometheus 服务器还提供了一套内置查询语言 PromQL,一个表达式浏览器以及一个用于浏览服务器上数据的图形界面。
Prometheus 数据模型
正如之前所述,Prometheus 收集时间序列数据。为了处理这些数据,它使用一个多维时间序列数据模型。这个时间序列数据模型结合了时间序列名称和称为标签(label)的键/值对,这些标签提供了维度。每个时间序列由时间序列名称和标签的组合作为唯一标识。
指标名称
时间序列名称:通常描述收集的时间序列数据的一般性质。例如,website_visits_total 为网站访问的总数。
名称可以包含 ASCII 字符,数字,下划线和冒号;
标签
标签为 Prometheus 数据模型提供了维度。它们为特定时间序列添加上下文。例如,total_website_visits 时间序列可以使用能够识别网站名称,请求 IP 或其他特殊标识的标签。Prometheus 可以在一个时间序列,一组时间序列或者所有相关的时间序列上进行查询。
标签共有两大类:插桩标签(instrumentation label)和目标标签(target label)。
插桩标签来自被监控的资源。例如,对于与 HTTP 相关的时间序列,标签可能会显示所使用的特定 HTTP 动词。这些标签在由诸如客户端或 exporter 抓取之前会被添加到时间序列中。
目标标签更多地与架构相关,它们可能会识别时间序列所在的数据中心。目标标签由 Prometheus 在抓取期间和之后添加。
时间序列由名称和标签进行标识(从技术上讲,名称本身也是名为 __name__
的标签)。如果你在时间序列中添加或更改标签,那么 Prometheus 会将其视为新的时间序列。
你可以理解 label 就是键值对形式的标签,并且新的标签会创建新的时间序列。标签名可以包含 ASCII 字符,数字和下划线。
带有__
前缀的标签名称保留给 Prometheus 内部使用。
采样数据
时间序列的真实值是采样的结果,它包括两个部分:
- 一个是 float64 类型的数值;
- 一个是毫秒精度的时间戳;
符号表示
结合这些元素,我们可以看到 Prometheus 如何将时间序列表示为符号(notation)。如下所示
1 | <time series name>{<label name>=<label value>, ...} |
例如,带有标签的 total_website_visits 时间序列可能如下所示
1 | total_website_visits{site="MageAPP", location="NJ", instance="webserver", job="web"} |
受限是时间序列名称,后面跟着一组键值对标签。通常所有时间序列都有一个 instance 标签(标识源主机或应用程序)以及一个 job 标签(包含抓取特定时间序列的作业名称)。
保留时间
Prometheus 专为短期监控和警报需求而设计。默认情况下,它在其数据库中保留 15 天的时间序列数据。如果要保留更长时间的数据,则建议将所需数据发送到远程的第三方平台。Prometheus 能够写入外部数据存储。
安全模型
Prometheus 可以通过多种方式进行配置和部署,关于安全有以下两个假设:
- 不受信任的用户将能够访问 Prometheus 服务器的 HTTP API,从而访问数据库中的所有数据。
- 只有受信任的用户才能访问 Prometheus 命令行、配置文件、规则文件和运行时配置。
从 Prometheus 2.0 开始,默认情况下某些 HTTP API 的管理功能被禁用。因此,Prometheus 及其组件不提供任何服务器端的身份验证、授权或加密。如果你需要在一个更加安全的环境中工作,则需要自己实施安全控制 —— 例如,通过反向代理访问 Prometheus 服务器或者正向代理 exporter。
Prometheus 生态系统
Prometheus 生态系统由 Prometheus 项目本身提供的组件以及丰富的开源工具和套件组成。生态系统的核心是 Prometheus 服务器,我们将在下一章进行详细介绍。此外还有 Alertmanager,它为 Prometheus 提供警报引擎并进行管理。
Prometheus 项目还包括一系列 exporter,用于监控应用程序和服务,并在端点上公开相关指标以进行抓取。核心 exporter 支持常见工具,如 Web 服务器、数据库等。许多其他 exporter 都是开源的,可以从 Prometheus 社区查看。
Prometheus 还发布了一系列客户端库,支持监控由多种语言编写的应用程序和服务。它们包括主流编程语言,如 Python、Ruby、Go 和 Java。其他客户端库也可以从开源社区获取。
参考连接
- Prometheus 官网: https://prometheus.io/
- Prometheus 文档: https://prometheus.io/docs/
- Ptometheus GitHub 主页: https://github.com/prometheus/
- Prometheus 源码: https://github.com/prometheus/prometheus
- Grafana 官网: https://grafana.com