我们如何用Grafana Alloy集群抓取近2000万条Prometheus指标

如果你希望自行运行Grafana Alloy集群,以获得高可用性或水平扩展能力,这篇文章正适合你。我们已经在自己的无代理exporter系统中这样做了。这个系统允许你从Amazon CloudWatch等服务商抓取数据,而无需在自己的基础设施中运行应用。系统基于Alloy集群构建,在本文写作时,已在Grafana Cloud提供的所有区域中服务于多达1950万条活跃序列(指标)。

它很好地满足了我们的扩展需求,因此我们想分享一些经验。本文将深入介绍Alloy集群的工作方式,如何结合无代理exporter使用它——这里以查询Amazon CloudWatch为例——以及如何简化Grafana Cloud中的抓取任务。

什么是Grafana Alloy集群?

Grafana Alloy是我们开源的OpenTelemetry Collector发行版,内置Prometheus流水线,并支持指标、日志、链路和性能剖析。其中一个出色功能是集群能力:可以配置一组Prometheus抓取任务,并将其分配到多个Alloy节点。集群通过基于gossip的协议协调成员关系和任务归属,与其他采用分布式系统实现的Grafana Cloud产品中的既有做法相似。

Grafana Cloud的无代理exporter是专门为Grafana Cloud基础设施开发并在其中运行的集成。这些集成直接在Grafana Cloud中配置,并运行在我们托管的Alloy集群上,因此你无需在自己的基础设施中部署Alloy或exporter。目前提供无代理exporter的服务包括AWS Observability CloudWatch指标、Confluent Cloud和Metrics Endpoint。

Alloy集群如何工作

本节重点介绍启用集群所需的Alloy配置,以及如何为集群提供要执行的组件。

以最基本的方式启用集群,包含两个部分:

  1. 运行Alloy二进制程序时,需要将cluster.enabled标志设置为true。根据部署Alloy的基础设施,可以通过命令行参数或Kubernetes Helm chart设置。如果要自定义集群的网络设置,命令行文档还说明了其他几个可能用到的集群标志。这一步建立集群的基础状态,使集群化组件能够分配到Alloy节点。
  2. 为零个或多个受支持的Alloy 组件配置并启用集群功能,具体见下方链接。这一步才会实际将工作分配到Alloy节点。

下面是基础Alloy配置的大致示例,采用UTF-8文本文件格式:

import.http "pipelines" {
  url = "https://api/pipelines"
  // Generally want this to be set higher
  // than poll_timeout
  poll_frequency = "120s"
  // Set to the write timeout of the HTTP
  // server which serves the configs
  poll_timeout = "90s"
  arguments {
    api_url_base = "https://api"
  }
}

基础配置中的这段代码告诉Alloy,从HTTP服务器获取并执行动态生成的配置块。API返回的纯文本响应体,大致如下:

argument "api_url_base" {}

discovery.http "cloudwatch" {
  url = format("%s/targets/cloudwatch", argument.api_url_base.value)
}

prometheus.scrape "cloudwatch" {
  clustering {
    enabled = true
  }
  targets = discovery.http.cloudwatch.targets
  forward_to = [prometheus.remote_write.cloudwatch.receiver]
  // We use the timestamps at which the metric is scraped,
  // rather than the timestamps reported by the metrics themselves.
  // This helps with alert queries.
  honor_timestamps = false
}

prometheus.remote_write "cloudwatch" {
  endpoint {
    url = "https://grafana-cloud-metrics/api/prom/push"
  }
}

// This hash is generated by the API and can help with
// debugging, e.g. getting a sense of whether each
// Alloy instance is using the same version of configuration.
output "pipelines_hash" {
  value = "c06d59a8dc5629d7457a9aa7cff36f46"
}

每个Alloy集群节点都必须收敛到完全相同的配置,集群才能在节点之间分配prometheus.scrape组件。抓取组件会分配给某个节点,并通过discovery.http块取得exporter配置的JSON数组,周期性地从无代理exporter采集指标。API还会计算前面其他配置块的哈希,以便通过实例的调试界面比较API提供的配置与各Alloy实例实际配置,从而发现传播问题。

深入了解Grafana Cloud无代理exporter

接下来以AWS Observability应用为例,更深入地了解无代理exporter。将AWS指标数据送入Grafana Cloud有多种方式。AWS Observability运行在Grafana Labs运营的Alloy集群上。使用当前Alloy集群系统创建CloudWatch指标抓取任务,其高层流程大致如下:

Alloy clustering workflow

流程始于Grafana Cloud API,它帮助管理并持久化托管抓取任务的配置,再通过HTTP以Alloy配置格式提供这些配置。随后,Grafana Alloy集群中的各节点周期性地从API拉取任务集合,并与其他节点通信,或利用通信结果决定自己应执行哪些任务。每个任务按固定时间间隔运行,并调用exporter,指定查询时间范围、要拉取的指标及其聚合函数。

exporter可能负责复杂的元数据操作,例如判断哪些指标最近确实有数据,或将特定时间序列关联到供应商特有的资源标识符。元数据关联的更多信息,见近期博客中的CloudWatch数据保真度部分。

Alloy集群如何改进Grafana Agent的抓取服务

如今,Grafana Alloy集群从Grafana Cloud API异步拉取抓取任务配置。此前则是Grafana Cloud API借助etcd集群,向Grafana Agent抓取服务推送配置,整体有状态程度更高。

Grafana Agent scraping service workflow

Grafana Agent抓取服务要求将集群成员状态以及抓取配置存入etcd或Consul这类分布式键值存储。因此,除了自己的独立持久化层,Grafana Cloud API还必须通过Grafana Agent配置管理API,以Agent的YAML格式持久化每份配置。

这种方式有两个主要缺点:

  1. 额外的持久化层会带来复杂的数据一致性故障模式,即双写问题。
  2. 维护额外的etcd持久化层并非易事。任何配置和交互复杂的软件系统,都可能出现导致服务中断的错误配置或错误交互。

Alloy的集群功能借助导入配置组件,从远程来源取得动态Alloy配置,从而消除了这两个问题。具体而言,我们主要使用import.http组件,配置Alloy节点调用Grafana Cloud API,生成最新的抓取任务配置集合。

迁移到Alloy集群

要让Alloy集群成为替客户抓取指标的唯一系统,我们必须迁出Grafana Agent及其抓取服务功能。Grafana Agent已经被弃用,其中抓取服务仍是beta功能,因此多数读者可能无需经历完全相同的过程。不过,我们仍想提供总体介绍,帮助你理解从Grafana Agent迁移到Alloy是什么样的工作。

总体上,需要改造Grafana Cloud API:将抓取任务配置从Agent抓取服务的etcd存储中移除,改为提供给Alloy拉取。

迁移准备大致如下:

  1. 在Grafana Cloud API中增加新路径,将prometheus.scrape和prometheus.remote_write组件作为Alloy 模块提供,使Alloy能够获取并运行它们。
  2. 为API及持久化任务数据增加标志,决定某个任务是否应通过新路径提供。
  3. 实现迁移工具,让一组任务可以通过新路径提供给Alloy,再删除Grafana Agent抓取服务中正在运行的这些任务副本。
  4. 部署新的Alloy节点,达到目标容量。
    • 为这些Alloy节点配置指向相关Grafana Cloud API路径的import.http块,并设置cluster.enabled运行标志。
    • 初步测试发现:在我们的部署条件下、相同抓取任务负载中,Alloy集群节点与Agent抓取服务节点的资源需求大致相同。

实际迁移大致如下:

  1. 迁移前,确保API已配置为把所有新建任务提供给部署好的Alloy节点。
  2. 随后运行迁移工具:先迁移少量小任务,其大小按总活跃序列数判断;然后逐步扩大批次,迁移剩余小任务;最后谨慎地逐一处理最大的任务,直到全部完成。
  3. 迁移立即取得了成功,但为稳妥起见,每批迁移后仍至少观察几天。最终移除已失去作用的Agent节点,拆除旧基础设施,迁移完成。

开始使用Alloy

采用Alloy集群功能很容易,甚至迁移全部生产抓取任务也很顺利。通过gossip协议,Alloy让我们可以选择适合服务需求的存储层组件,而无需担心额外的持久化要求。只需输出Alloy文本格式配置;使用Go的模板包实现这一点并不复杂。

希望你也像我们一样喜欢使用Alloy!以下博客和文档可以帮助入门:

  • 阅读这篇近期博客,了解在Grafana中可视化Amazon CloudWatch指标的各种方式。
  • 有关Alloy入门及一般使用的最新信息,请参阅文档。
  • 如果重点关注Alloy集群,可以在这份文档找到最新信息。

Grafana Cloud提供指标、日志、链路、仪表板等功能的入门方式。原文介绍其长期免费层和面向不同场景的方案,并邀请读者免费注册。(保留原文产品介绍;当前方案以官网为准。)


原文:我们如何用Grafana Alloy集群抓取近2000万条Prometheus指标;作者:Tristan Burgess、Andrii Kushch;日期:2024-06-06。原文及源码权利归原作者和相应权利人所有。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容