1. 引言
Prometheus 作为目前最主流的可观测开源项目之一,已经成为云原生监控的事实标准,被众多企业广泛应用。在使用 Prometheus 的时候,我们经常会遇到全局视图的需求,但是数据确分散在不同的 Prometheus 实例中,遇到这种情况该怎么解决呢?本文列举了社区一般解决方案,同时给出了阿里云的全局视图解决方案,最后给出了某客户基于阿里云 Prometheus 的实践案例,希望能给您带来启发与帮助。
2. 背景
在使用阿里云 Promtheus 时,由于地域的限制、业务原因或者其他原因,经常会遇到 Prometheus 多实例的场景。如下图所示,某用户在杭州区域有多个 Prometheus “通用”实例。在多实例的背景下,我们经常会遇到一些问题。
2.1 问题 1-单一 Grafana 大盘数据源
我们知道 Grafana 大盘是观测 Prometheus 数据最常规、最普遍的方式。通常情况下,每观测一个 Prometheus 集群就需要创建一个数据源,假设我有 100 个 Prometheus 集群,就需要创建 100 个数据源。听着是个很麻烦的事情,如果你还能接受,那么继续往下看。
在编辑 Grafana panel 并填写 PromQL 时我们可以选择数据源,但是为了保证数据查询和展示的一致性与简洁性,Grafana 仅允许一个 panel 使用一个数据源。
如果我们需要在一个大盘内同时绘制多个数据源的 panel,那么使用以上 100 个数据源时就会产生 100 个 panel,并且需要编辑 100 次 panel 并编写 100 次 PromQL,非常不利于运维。理想状态下应该是合并为一个 panel,并且每个数据源一个时间线,不仅方便指标监控,更是大大减少大盘的维护动作。
2.2 问题 2-实例间数据计算与查询
当不同的业务使用了不同的 Prometheus 实例,但这些实例都有在上报着相同的指标,我们希望将这些数据做聚合(sum)、增长率(rate)等运算,由于存在着实例间的存储隔离,这样的操作是不允许的。同时我们并不希望把这些数据都上报到同一个实例中,因为根据业务场景,可能这些数据来自不同的 ACK 集群、ECS、Flink 实例等,甚至数据来源不是同一个地区,因此保持实例级别的隔离是有必要的。
3. 社区解决方案
所以,针对多 Prometheus 实例存在的上述问题,社区是如何解决的呢?
3.1 Federation 方案
Prometheus Federation 机制是 Promehteus 本身提供的一种集群化的扩展能力,但是也可以用于解决数据的中心化查询问题。当我们要监控的服务很多的时候,我们会部署很多的 Prometheus 节点分别 Pull 这些服务暴露的 Metrics,Federation 机制可以将这些分别部署的 Prometheus 节点所获得的指标聚合起来,存放在一个中心点的 Prometheus。如下图所示为常见的 Federation 架构:
边缘节点每一个 Prometheus 实例都会包含一个/federate 的接口,用于获取一组指定的时间序列的监控数据,Global 节点只需要配置一个采集任务,用于从边缘节点获取监控数据即可。为了更好的理解 Federation 机制,下面给出了 Global Prometheus 的配置文件的配置。
scrape_configs: - job_name: 'federate' scrape_interval: 10s honor_labels: true metrics_path: '/federate' # 根据实际业务情况进行Pull metrics,通过match参数,配置要拉取的Metrics params: 'match[]': - '{job="Prometheus"}' - '{job="node"}' static_configs: # 其他 Prometheus 节点 - targets: - 'Prometheus-follower-1:9090' - 'Prometheus-follower-2:9090'
3.2 Thanos 方案
对于开源的 Prometheus 版本,我们可以使用 Thanos 实现聚合查询,如下为 Thanos 的 Sidecar 部署模式:
这张图中包含了 Thanos 的几个核心组件(但并不包括所有组件):
- Thanos Sidecar:连接 Prometheus,将其数据提供给 Thanos Query 查询,并且将其上传到对象存储以供长期存储。
- Thanos Query:实现了 Prometheus API,提供全局查询视图将来 StoreAPI 提供的数据进行聚合最终返回给查询数据的 client(如 Grafana)。
- Thanos Store Gateway:将对象存储的数据暴露给 Thanos Query 去查询。
- Thanos Compact:将对象存储中的数据进行压缩和降低采样率,加速大时间区间监控数据查询的速度。
- Thanos Ruler:对监控数据进行评估和告警,还可以计算出新的监控数据,将这些新数据提供给 Thanos Query 查询并且/或者上传到对象存储,以供长期存储。
- Thanos Receiver:从 Prometheus 的远程写入 WAL 接收数据,将其公开和/或上传到云存储。
那 Thanos 如何实现 global 查询的呢?
Thanos Query 实现了 Prometheus 的 HTTP API,这样查询 Prometheus 监控数据的 client 就不直接查询 Prometheus 本身了,而是去查询 Thanos Query,Thanos Query 再去下游多个存储了数据的地方查数据,最后将这些数据聚合去重后返回给 client,从而实现了 global 查询。而为了实现 Thanos Query 去查下游分散的数据,Thanos 为此抽象了 Store API 的内部 gRPC 接口,其它一些组件通过这个接口来暴露数据给 Thanos Query。
在上述的架构中单个的 Prometheus 会将采集的数据存到本机磁盘上,每个 Prometheus 附带部署一个 Sidecar,这个 Sidecar 实现 Thanos Store API,由于 Prometheus 本地磁盘有限,所以对于长时间周期的存在通过 Sidecar 的 Thanos Store API 会将数据存储在对象存储;无论对于单个 Prometheus 上的数据查询还是对象存储的查询都是基于“Store API”,如下对查询进行进一步的抽象。
3.3 Prometheus Remote Write 方案
Remote Write 也是解决 Prometheus 多实例全局查询的有效解决方案,其基本思想与 Prometheus Federation 机制非常类似,将分别部署的 Prometheus 节点所获得的指标利用 Remote Write 机制存放在一个中心点的 Prometheus 或者第三方存储中。
用户在 Prometheus 配置文件中指定 Remote Write 的 URL 地址,一旦设置了该配置项,Prometheus 将采集到的样本数据通过 HTTP 的形式发送给适配器 (Adaptor),而用户则可以在适配器中对接外部任意的服务。外部服务可以是开源 Prometheus,也可以是真正的存储系统,也可以是公有云的存储服务。
如下为样例,修改 Prometheus.yml 添加 Remote Storage 相关的配置内容。
remote_write: - url: "http://*****:9090/api/v1/write"
4. 阿里云解决方案
4.1 阿里云 Prometheus 全局聚合实例解决方案
4.1.1 阿里云 Prometheus 全局聚合实例方案介绍
阿里云推出了“Prometheus 全局聚合实例”,其目标是实现跨多个阿里云 Prometheus 实例的数据聚合,在查询数据时同时从多个实例中读取数据,其原理为“查询时指标聚合”。
使用阿里云全局聚合实例(以下简称 Gloabal View)可以保证单个阿里云 Prometheus 实例间的数据隔离,即每个 Prometheus 实例后端拥有独立的存储,不是通过合并数据到一个中央存储,而是在查询时动态地从各个实例的存储中检索需要的数据。这样,当用户或者前端应用程序发起查询请求时,Global View 会并行地对所有相关 Prometheus 实例进行查询,并将结果汇总,提供一个统一的视图。
4.1.2 对比分析
下面针对开源 Prometheus Federation 以及 Thanos 方案以及阿里云全局聚合实例方案进行简单的汇总说明。
1)Prometheus Federation
虽然 Prometheus Federation 能解决全局聚合查询,但是还存在一些问题。
- 边缘节点和 Global 节点依然是单点,需要自行决定是否每一层都要使用双节点重复采集进行保活,也就是仍然会有单机瓶颈。
- 对历史数据的存储问题仍旧未得到解决,必须依赖第三方存储,切缺少对历史数据的降准采样能力。
- 整体运维成本比较高。
- 可扩展性较差,添加或移除 Prometheus 实例需要修改配置文件。
2)Thanos Federation
- 架构比较复杂,运维成本较高。
- 仍存在 Prometheus 副本的单点问题。
- 时间线发散的情况下,支持的上限不够,不提供维度发散场景优化。
- 不支持降采样,长周期查询性能不高。
- 不支持算子下推,大数据量的请求性能有限,并且处理开销大。
3)阿里云全局聚合实例
- Prometheus 实例托管、免运维。
- 支持图形化界面进行多实例的管理,灵活性强、可扩展性高。这种模式允许系统轻松地添加或移除阿里云 Prometheus 实例,而不需要重新配置整个存储系统。
- 不占用额外的存储空间。由于没有将数据复制到集中的存储中,这种方法可以节约存储空间,每个 Prometheus 实例只需要维护自己的数据集。在不额外配置存储的情况下,查询到的数据仅是临时用于展示,真正的数据持久化仍然归于被聚合的实例。
- 隔离性:每个实例的自治性能够提高系统的容错性,因为单个实例的问题不会直接影响到其他实例。
- 支持跨 region 实例以及跨账号实例聚合,满足企业个性化的需求。
但是需要注意的是 Thanos Federation 与阿里云全局聚合实例都是非合并数据的方式实现全局查询。由于需要在查询时从多个数据源检索数据,这可能会导致查询性能下降,特别是当查询涉及大量不需要的数据时,需要等待多个数据源筛选出需要的数据,等待这些数据处理的过程可能导致查询超时或长时间等待。
4.1.3 阿里云 Prometheus 全局聚合实例实践
阿里云 Prometheus 极大简化了用户的操作,无需手动部署 Prometheus 扩展组件,用户通过控制台操作便可实现全局视图的功能。在创建 Prometheus 实例时选择“全局聚合实例”,勾选需要聚合的实例,并选择查询前端所在的地区(影响查询域名的生成),点击“保存”后即可。
进入创建好的全局聚合实例,点击任意大盘,可以看到该实例已经能查询到刚刚聚合的其他实例数据。实现了我们在 Grafana 一个数据源查询多个实例数据的需求。
4.2 阿里云 Prometheus Remote Write 解决方案
4.2.1 阿里云 Prometheus Remote Write 解决方案
阿里云 Prometheus remote write 的能力是阿里云 Prometheus 数据投递的原子能力。Prometheus 数据投递的原理为“存储时的指标聚合”,其目标是将跨多个 Prometheus 实例的数据通过 ETL 服务提取出来,再写入某个聚合实例的存储中。
通过这种方式,相同的 Prometheus 数据可以同时存储在不同的实例中:
1. 在被聚合的 Prometheus 实例中,存储着该实例所有的原始数据,包括期望被聚合查询的实例以及其他数据。用于原业务场景中单实例的查询。
2. 在中央/聚合 Prometheus 中,存储着其他“被聚合实例”的“期望被聚合的数据”,在统一管理的场景下,可以通过该实例获取全局视图的查询,执行跨实例数据的搜索。
4.2.2 阿里云 Prometheus Remote Write VS 社区 Prometheus Remote Write
1)Prometheus Remote Write
开源 Remote Write 的形式最大的弊端在于对 Prometheus Agent 的影响,在 Agent 设置 Remote Write 会增加 Agent 的资源消耗,影响数据采集的性能,而这一点往往是致命的。
2)阿里云 Prometheus Remote Write
阿里云 Prometheus Remote Write 的优势还是非常明显的。
- 查询性能高:因为只存储了必要的聚合数据,聚合 Prometheus 实例的查询响应时间更短,极大地提升了用户体验。此外,在查询时本质上只是对一个 Prometheus 实例进行操作,而非多个实例,读写的性能、计算的性能更高。
- 数据质量高:经过筛选后的数据更加干净,没有不必要的 "脏数据",这有助于进行更加精准和有效的数据分析。
- 提供丰富的 ETL 能力: 在写入聚合实例之前提供丰富的处理能力,如过滤筛选、指标富化等。
- 图形化配置,操作简单便捷。
同时当然也有一些劣势,大家需要综合权衡取舍。
- 费用问题:由于需要额外的 Prometheus 实例来作为聚合和全局查询的存储点,这意味着需要额外的 TSDB 后端存储需要被聚合的数据,这些独立的存储空间是需要计费的。
- 网络消耗:在数据投递过程中,跨网络的数据传输会增加带宽占用,特别是在跨数据中心或宽带有限的环境中,所以需要进行合理的评估。
4.2.3 阿里云 Prometheus Remote Write 使用
1. 在左侧导航栏,选择 Prometheus 监控 > 数据投递(beta),进入可观测监控 Prometheus 版的数据投递页面。
2. 在数据投递页面的顶部菜单栏,选择地域,然后单击新建任务。
3. 在对话框中输入任务名称和任务描述后,单击确定。4. 在任务编辑页面,配置数据源和投递目标。
配置项 | 说明 | 示例 |
Prometheus 实例 | 被投递的 Prometheus 数据源。 | c78cb8273c02***** |
数据过滤 | 根据白名单或黑名单模式填入需要过滤的指标,通过 Label 筛选投递数据。支持正则表达式,多个条件换行,多个条件为且(&&)的关系。 | __name__=rpc.*job=apiserverinstance=192.* |
5. 配置 Prometheus Remote Write 地址以及认证方式。
Prometheus 类型 | 地址获取方式 | 要求 |
阿里云 Prometheus | Remote Write 和 Remote Read 地址使用说明[1]
|
认证方式选择 B“A 运维平台” c Auth,并输入具备 AliyunARMSFullAccess 权限的 RAM 用户的 AK 和 SK。AK 和 SK 的获取方式,请参见查看 RAM 用户的 AccessKey 信息[2]
|
自建 Prometheus | 官方文档[3] | 1. 自建 Prometheus 的版本为 2.39 以上版本。2. 需配置 out_of_order_time_window。具体操作,请参见 promlabs[4]。 |
6. 配置网络。
Prometheus 类型 | 网络模式 | 网络要求 |
阿里云 Prometheus | 公网 | 无 |
自建 Prometheus | 公网 | 无 |
专有网络 | 请选择自建 Prometheus 实例所在的 VPC,并确保您填写的 Prometheus Remote Write 地址在该 VPC、交换机和安全组内可访问。 |
4.3 阿里云解决方案总结与选择
阿里云提供了全局聚合实例以及数据投递-Remote Write解决方案各有优劣。
Prometheus 全局聚合实例的设计理念是在保持 Prometheus 实例的存储独立性的同时,提供一个统一的接口对多个实例进行查询来实现全局视图。该方案的核心理念为“查询时指标聚合”,也就是说数据原封不动地存储在多个实例中,当统一查询时才将多个实例的数据获取并聚合。这种方法有其明显的优点,如节省存储空间,但也存在一些挑战,对于实例数量较多、数据量大的场景查询性能会受较大影响。
Prometheus 数据投递-Remote Write 的设计理念是将查询的流量转化为数据写入的流量,它消耗了额外的存储空间提供多实例聚合数据的方案,它通过在写入之前筛选数据,使得中心实例精简地存储着聚合数据。该方案的核心理念为“存储时指标聚合”,此时多个实例的数据副本将存储在统一中心化实例中,对多个实例的查询将转化为单实例查询,大大提升了查询速率与数据质量。
方案 | 核心理念 | 存储空间 | 查询方式 |
全局聚合实例 | 查询时指标聚合 | 不额外消耗存储空间 | 多实例查询 |
数据投递-Remote Write | 存储时指标聚合 | 需要额外存储聚合数据 | 单实例查询 |
5. 案例分析
5.1 某客户运维平台可观测现状
5.1.1 介绍
下图所示为某客户的内部运维平台,这里暂且称为“A 运维平台”,客户公司利用 A 运维平台进行公司内部 K8s 集群的生命周期管理。在 A 运维平台中,只能针对单个集群进行相关监控数据的查看,当有多个集群有问题需要排查时,只能一个一个处理。
同样的,在使用 Grafana 时,当前大盘只能查看某个集群的具体数据,无法对多个集群同时监控。
此时 SRE 团队无法对所有集群状态有全局的视角,难以准确获取该产品的健康状态。在平时的运维工作中,大多依赖告警提示某个集群处于非健康状态。目前 A 运维平台托管了上百个集群,全部依赖告警会有消息过多的风险,导致等级较高的故障无法快速定位。
5.1.2 诉求
当前在“A 运维平台”的运维管理面临一个挑战:缺少对所有地区集群状态的一目了然的全局视图。“A 运维平台”的目标是配置单一的 Grafana 大盘,通过引入单一的数据源,实现对个产品线整所有租户集群运行状况的实时监控这应。包括关键指标的可视化,例如集群的整体状态(包括集群的数量、各节点和 Pod 的数量、全网集群的 CPU 使用情况等),以及\APIServer 的 SLO(服务水平目标)状态(诸如全网非 500 响应的动词比例、50X 错误的详细信息、请求成功率等)。
通过这个精心设计的大盘,运维团队可以迅速锁定任何处于非健康状态的集群,快速概览业务量,并对潜在问题进行快速调查,大幅提升运维效率和响应速度。这样的集成不仅优化了监控流程,也为运维团队提供了一个强大的工具,以确保系统的稳定性和服务的连续性。
5.1.3 难点
跨大洲数据传输:“A 运维平台”的场景涉及到全球所有区域,SRE 团队在运维时希望能在杭州区域的大盘查看全球所有区域的实例数据,这就涉及到了跨大洲的数据传输。当在 Grafana 进行跨大洲的实例查询时,因为网络传输的延迟存在,经常性地出现查询超时的问题。
请注意:当您使用 Promethues 配置数据跨境时。您同意并确认,您完全拥有该份业务数据的所有处置权限,对数据传输的行为全权负责。您应确保您的数据传输符合所有适用法律,包括提供充分的数据安全保护技术和策略,履行获得个人充分明示同意、完成数据出境安全评估和申报等法定义务,且你承诺您的业务数据不含任何所适用法律限制、禁止传输或披露的内容。如您未遵守前述声明与保证,您将承担对应的法律后果,导致阿里云和或其他关联公司遭受任何损失的,您应承担赔偿责任。
单实例数据量过大:并非所有的数据都需要全区域全实例聚合查询,全球视角的运维一般只关心某几个表示集群状态的指标;或是针对某些指标,只关心几个特定的 label(namespace)。随着被“A 运维平台”托管的集群增加、租户增加,上报指标的 label 越来越多样化,可能涉及到指标纬度发散的问题。目前针对指标纬度发散的问题业界仍没有统一的解决方案,此时查询会大量消耗 TSDB 的内存。在单 Prometheus 实例的场景下对这类发散指标查询时就已经给 TSDB 实例很大的压力,当一次性获取“A 运维平台”所有 Prometheus 实例数据时给服务器的压力过大。
超大空间跨度的查询:需要对某几个指标,把当前区域/全球的所有实例数据求和等计算。在问题 2 单实例数据量的基础上,推广至“A 运维平台” 上百个 Prometheus 实例,此时所有实例涉及到的数据量更加庞大。当 TSDB 进行查询、筛选、计算操作时,会占用大量的内存,一般的计算资源配额无法满足。
5.2 通过数据投递实现中心化数据查询
5.2.1 方案选型
是选择全局聚合实例还是数据投递?在“A 运维平台”的场景下,针对以上讨论的需求以及难点,选择数据投递是更好的方案。有如下原因:
1)传输延迟容忍度
当使用数据投递时,链路能承受更大的网络延迟。
- 当使用全局聚合实例查询时:
- 每次请求都会产生多个跨大洲的网络延迟。在测试过程中,跨大洲网络传输延迟在 500ms~700ms 间,在特殊时段、网络波动等情况下延迟甚至能达到 1min+,极易造成查询超时。
- “A 运维平台”实例部署在全球各个地区,当其中 99% 的数据都成功查询,某个地区由于网络波动导致查询超时,那么其他 99% 成功查询到的数据也就不可用了,对数据齐全度要求很高。
- 在查询时客户的 PromQL、时间跨度是不固定的,导致查询的数据量是任意的。当查询数据量过大,数据可能会分到多个 HTTP 包传输(受限于网络提供商),此时网络延迟很大。
- 当使用数据投递时:
- 数据投递的数据网络传输不会随着用户查询量改变,而是将各 Prometheus 实例采集到的数据实时的投递至中心化 Prometheus 实例中,此时数据包不超过 1MB 大小,网络延迟维持在固定的范围。
- 聚合数据都保存在中心化 Prometheus 实例中,因此只需保证对该实例的查询不出错即可,无需考虑查询齐全度的问题。
- 即使经过了超大的跨大洲网络传输,我们仍然能通过攒批、重试等方式保证数据成功写入了中心 Prometheus 实例。尽管中心实例中的最新数据与当前时间有分钟级的延迟,查询成功率有了保证。
2)节省计算资源
执行 PromQL 查询时,指标的时间线数量决定了查询所需的 CPU、内存资源。也就是说指标的 label 越多样,所消耗的资源就越多。
- 当使用全局聚合实例查询时:
- 被聚合的实例存储着所有的原始数据,查询的资源消耗较大。由于 TSDB 的特性,即使进行了 label 的筛选,仍有可能将该时间段的全量数据加载到内存中。在“A 运维平台”的场景中,由于每次查询都涉及到海量数据,因此对内存的消耗是非常大的,往往会触发查询限流。
- 在测试的过程中,查询时间跨度为 1 小时,需要等待 30 秒后才能返回结果。
- 当使用数据投递时:
- 被查询的实例仅有一个,并且该实例存储的数据经过前置筛选,是我们所关心的需要聚合的相关数据。假设我们要在杭州地区查询全球上百个实例的数据,此时底层相当于只查询当前杭州地区的某个实例,效率很高。
- 在测试的过程中,查询时间跨度为 1 小时,只需等待 1 秒就能返回结果。
总的来说,当我们选择多实例数据统一管理的方案时,除了考虑是否需要额外的存储空间,针对业务场景来说查询成功率是更重要的参考指标。
在“A 运维平台”的场景下,因为涉及到了跨大洲、海量实例、海量数据,因此查询时再进行指标聚合容易产生网络请求超时、数据库查询限流、数据库内存消耗过大等问题,使得查询成功率降低。
而使用存储时指标聚合的数据投递方案,将数据提前存储至中心化实例,把查询的网络传输转化为写数据的网络传输,把全球多实例的查询请求转换为当前地区实例的查询,查询成功率高并且满足业务场景。
5.2.2 方案架构
如图为 Prometheus 数据投递-Remote Write 的产品形态。数据投递服务由两个组件组成,一是 Prometheus 投递组件,该组件负责从源头 Prometheus 实例获取数据,经过指标过滤、格式化后发送给公网转发服务组件。公网转发服务组件负责将数据路由,通过公网的方式把数据发送至杭州的中心化实例。
在未来的计划中,我们将使用事件总线 EventBridge 替换现有公网转发服务组件,以支持更多的投递目标生态。
5.3 效果
通过 Prometheus 数据投递-Remote Write 功能,将“A 运维平台”全球多个区域的上百个实例的数据投递至杭州的一个中心化实例中,配置了 Grafana 的单一数据源,配置大盘后即可对“A 运维平台”管理的所有集群进行可视化监控。杜绝了之前的每个集群一个数据源的配置方式,大大方便了运维的操作。
6 广告时间
6.1 阿里云可观测监控 Prometheus 版 VS 开源 Prometheus
阿里云可观测监控 Prometheus 版全面对接开源 Prometheus 生态,支持类型丰富的组件监控,覆盖绝大部分开源基础设施软件指标采集能力。提供多种开箱即用的预置监控大盘,并集成丰富的 Kubernetes 基础监控以及常用服务预设看板,且提供全面托管的 Prometheus 服务。阿里云可观测监控 Prometheus 版的优势可以归纳为“开箱即用”、“低成本”、“开源兼容”、“数据规模无上限”、“高性能”、“高可用性”。
6.2 产品计费
目前,可观测监控 Prometheus 版已开启全新按数据写入量计费模式,并每月提供 50GB 免费额度。每日上报 1000 万指标,指标数据存储 90 天,仅需 37 元。
相关链接:
[1] Remote Write 和 Remote Read 地址使用说明
[3] 官方文档
[4] promlabs
参考文档:
[1] 参考一
[2] 参考二
[3] 参考三
[4] 参考四
[5] 参考五
作者:淡唯(啃唯)、阳其凯(逸陵)