vlambda博客
学习文章列表

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成

Integrating Long-Term Storage with Prometheus

Prometheus 的单实例设计使得维护大型历史数据集变得不切实际,因为它受到本地可用存储量的限制。拥有跨越大周期的时间序列可以进行季节性趋势分析和容量规划,因此,当数据集不适合本地存储时,Prometheus 通过将数据推送到第三方集群存储系统来提供这一点。在本章中,我们将研究远程读写 API,以及在 Thanos 的帮助下交付对象存储的指标。这将提供有关如何解决此要求的选项,从而实现多种架构选择。

简而言之,本章将涵盖以下主题:

  • Test environment for this chapter
  • Remote write and remote read
  • Options for metrics storage
  • Thanos remote storage and ecosystem

Test environment for this chapter

在本章中,我们将重点关注集群存储。为此,我们将部署三个实例来帮助模拟 Prometheus 生成指标的场景,然后我们将介绍一些有关如何将它们存储在对象存储解决方案中的选项。这种方法不仅可以让我们探索所需的配置,还可以了解一切如何协同工作。

我们将使用的设置类似于下图:

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成
Figure 14.1: Test environment for this chapter

在下一节中,我们将解释如何启动并运行测试环境。

Deployment

要启动新的测试环境,请移至此路径,相对于存储库根目录,如下所示:

cd ./chapter14/

确保没有其他测试环境在运行并启动本章的环境,如下所示

vagrant global-status
vagrant up

您可以使用以下命令验证测试环境的成功部署:

vagrant status

这将输出以下内容:

Current machine states:

prometheus                running (virtualbox)
storage                   running (virtualbox)
thanos                    running (virtualbox)

This environment represents multiple VMs. The VMs are all listed above with their current state. For more information about a specific VM, run `vagrant status NAME`.

当部署任务结束时,您将能够使用您最喜欢的支持 JavaScript 的 Web 浏览器验证主机上的以下端点:

服务

端点

普罗米修斯

http://192.168.42.10:9090

灭霸边车

http://192.168.42.10:10902

对象存储

访问密钥:strongACCESSkey

密钥:strongSECRETkey

http://192.168.42.11:9000

灭霸查询器

http://192.168.42.12:10902

您应该能够使用以下命令之一访问所需的实例:

实例

命令

普罗米修斯

vagrant ssh prometheus

贮存

vagrant ssh 存储

灭霸

vagrant ssh thanos

Cleanup

完成测试后,只需确保您在 ./chapter14/ 中并执行以下命令:

vagrant destroy -f

不要太担心;如果需要,您可以轻松地再次启动环境。

Remote write and remote read

远程写入和远程读取分别允许 Prometheus 推送和拉取样本:远程写入通常用于实现远程存储策略,而远程读取允许 PromQL 查询透明地定位远程数据。在以下主题中,我们将深入介绍这些功能中的每一个,并提供一些可以使用它们的示例。

Remote write

远程写入是 Prometheus 非常抢手的功能。它最初是作为对以 openTSDB、InfluxDB 和 Graphite 数据格式发送样本的原生支持而实现的。但是,很快就决定不支持每个可能的远程系统,而是提供一种适合构建自定义适配器的通用写入机制。这启用了与 Prometheus 路线图分离的自定义集成,同时也开启了在这些桥中支持读取路径的可能性。作为示例,远程写入的系统特定实现已从 Prometheus 二进制文件中删除,并转换为独立的适配器。依赖适配器和授权社区以便它可以构建所需的任何集成的逻辑遵循我们在 第 12 章选择正确的服务发现,用于构建自定义服务发现集成。

Prometheus 使用与 Prometheus 内部无关的非常简单的格式将单个样本发送到远程写入端点。另一端的系统甚至可能不是存储系统,而是流处理器,例如 Kafka 或 Riemann。在定义远程写入设计时,这是一个艰难的决定,因为 Prometheus 已经知道如何创建高效的块并且可以通过网络发送这些块。块会使支持流系统变得不切实际,并且发送样本对于适配器来说更容易理解和更容易实现。

随着 Prometheus 2.8 的发布,远程写入是一个极大增强的目标。以前,当指标无法传送到远程写入端点(由于网络或服务问题)时,只有一个小缓冲区来存储数据。如果该缓冲区被填满,指标将被丢弃,并永久丢失到那些远程系统。更糟糕的是,缓冲区可能会产生背压并导致 Prometheus 服务器由于 Out of Memory (OOM) 错误而崩溃。由于远程写入 API 开始依赖 Write-Ahead Log (WAL) 进行簿记,因此不再发生这种情况。现在远程写入不再使用缓冲区,而是直接从 WAL 读取,WAL 包含所有正在运行的事务和抓取的样本。在远程写入子系统上使用 WAL 可以使 Prometheus 内存使用更加可预测,并允许它在与远程系统的连接中断后从中断的地方恢复。

在配置方面,以下代码片段说明了在 Prometheus 中设置远程写入端点所需的最少代码:

remote_write:
  - url: http://example.com:8000/write

由于远程写入是与外部系统交互的另一个实例,所以 external_labels 在发送之前也会应用于样本。当使用多个 Prometheus 服务器将数据推送到同一位置时,这还可以防止远程端的指标冲突。远程写入还支持 write_relabel_configs 以允许您控制发送哪些指标以及丢弃哪些指标。此重新标记在应用外部标签后运行。

在本章后面,我们将讨论一个相当新的(和实验性的)Thanos 组件,称为 receiver,作为远程​​写入使用的一个实际示例。

Remote read

在远程写入功能可用后,远程读取请求开始流动。想象一下,将 Prometheus 数据发送到远程端点,然后必须学习一种新的查询语言,例如 InfluxQL(InfluxDB 查询语言)来访问上述数据。包含此功能可以对存储在 Prometheus 服务器外部的数据透明地使用 PromQL,就好像它在本地可用一样。

针对远程数据运行的查询被集中评估。这意味着远程端点只发送请求的匹配器和时间范围的数据,并且 PromQL 应用于发起查询的 Prometheus 实例。再一次,在设计 API 时选择集中式(而不是分布式)查询评估是一个关键决定。分布式评估可以分散每个查询的负载,但会迫使远程系统理解和评估 PromQL 并在数据不相交时处理大量极端情况,从而大大增加了 实现复杂性上述系统。集中评估还允许远程系统对请求的数据进行下采样,这极大地改进了具有很长时间范围的查询。

远程读取可能有用的一个示例是协助 Prometheus 主要版本之间的迁移,例如从 Prometheus v1 到 Prometheus v2。后者可以配置为从前者远程读取,从而使旧实例只读(未配置抓取作业)。这使用 v1 实例作为美化的远程存储,直到其指标不再有用。使该策略的实施者绊倒的一个常见问题是,配置远程读取的 Prometheus 实例中的 external_labels 需要在来自 Prometheus 实例的 external_labels 中匹配读。

另一方面,Prometheus 本身的远程读取端点的示例在前一章中看到(第 13 章Prometheus 的扩展和联合):Thanos sidecar 使用本地 Prometheus 实例的远程读取 API 来获取 Thanos 查询器请求的时间序列数据。

配置方面,设置 Prometheus 进行远程读取非常简单。以下片段显示了配置文件的必需部分:

remote_read:
  - url: http://example.com:8000/read

remote_read 部分还允许您使用 required_matchers 指定匹配器列表,这些匹配器需要出现在选择器中以查询给定端点。这对于不是存储的远程系统或仅将指标的子集写入远程存储,因此需要将远程读取限制为这些指标时很有用。

Options for metrics storage

默认情况下,Prometheus 在使用自己的 TSDB 管理指标的本地存储方面做得很好。但在某些情况下,这还不够:本地存储受到 Prometheus 实例本地可用磁盘空间量的限制,这对于较长的保留期(例如年)和超出数量的大数据量来说并不理想可以附加到实例的磁盘空间。在以下部分中,我们将讨论本地存储方法,以及当前可用的远程存储选项。

Local storage

Prometheus 开箱即用的时间序列数据存储解决方案就是本地存储。它更易于理解和管理:数据库位于单个目录中,如果需要,可以轻松备份、恢复或销毁。通过避免集群,Prometheus 在面对网络分区时确保行为正常;您不希望您的监控系统在您最需要的时候出现故障。高可用性通常通过简单地运行两个具有相同配置的 Prometheus 实例来实现,每个实例都有自己的数据库。但是,此存储解决方案并未涵盖所有用例,并且存在一些缺点:

  • It's not durable – in a container orchestration deployment, the collected data will disappear when the container is rescheduled (as the previous data is destroyed and the current data is started afresh) if persistent volumes are not used, while in a VM deployment, the data will be as durable as the local disk.
  • It's not horizontally scalable using local storage means that your dataset can only be as big as the disk space you can make available to the instance.
  • It wasn't designed for long-term retention, even though, with the right metric criteria and cardinality control, commodity storage will go a long way.

这些缺点是为了确保中小型部署(迄今为止更常见的用例)工作良好,同时也使高级和大规模用例成为可能而进行权衡的结果。警报和仪表板,在日常运营监控或故障排除持续事件的背景下,最多只需要几周的数据。

在全力以赴长期保留的远程度量存储系统之前,我们可能会考虑通过使用 TSDB admin API 端点来管理本地存储,即 snapshotdelete_series。这些端点有助于控制本地存储。正如我们在 第 5 章中提到的,运行 Prometheus服务器,TSDB管理API默认不可用; Prometheus 需要以 --web.enable-admin-api 标志启动,以便启用 API。

在本章的测试环境中,您可以尝试使用这些端点并评估它们的目标。通过连接 prometheus 实例,我们可以验证 TSDB admin API 是否已启用,并使用以下命令查找本地存储路径:

vagrant@prometheus:~$ systemctl cat prometheus
...
    --storage.tsdb.path=/var/lib/prometheus/data \
    --web.enable-admin-api \
...

/api/v1/admin/tsdb/snapshot 端点发出 HTTP POST 将触发一个新快照,该快照将在快照目录中存储可用块。快照是使用硬链接制作的,这使得它们非常节省空间,只要 Prometheus 仍然有这些块。以下说明说明了如何处理所有内容:

vagrant@prometheus:~$ curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot
{"status":"success","data":{"name":"20190501T155805Z-55d3ca981623fa5b"}}

vagrant@prometheus:~$ ls /var/lib/prometheus/data/snapshots/
20190501T155805Z-55d3ca981623fa5b

然后您可以备份快照目录,当需要查询历史数据时,可以通过--storage.tsdb.path将快照目录用作另一个Prometheus实例的TSDB存储路径。请注意,--storage.tsdb.retention.time 可能需要根据您的数据持续时间进行调整,因为 Prometheus 可能会开始删除保留期之外的块。

当然,这不会阻止 TSDB 的增长。为了管理这方面,我们可以使用 /api/v1/admin/tsdb/delete_series 端点,这对于每周甚至每天的维护很有用。它通过带有一组匹配选择器的 HTTP POST 请求进行操作,这些匹配选择器将所有匹配的时间序列标记为删除,如果还发送了时间范围,则可选择将删除限制在给定的时间窗口内。下表概述了相关 URL 参数:

网址参数

说明

match[]=<选择器>

一个或多个匹配选择器,例如 match[]={__name__=~"go_.*"}

(删除名称以 go_ 开头的所有指标)

开始=<时间戳>

RFC 3339 或 Unix 格式的删除开始时间(可选,默认为最早的可能时间)

end=<unix_timestamp>

RFC 3339 或 Unix 格式的删除结束时间(可选,默认为可能的最晚时间)

POST请求执行后,返回HTTP 204。这不会立即释放磁盘空间,因为它必须等到下一个 Prometheus 压缩事件。您可以通过请求 clean_tombstones 端点来强制执行此清理,如以下说明所示:

vagrant@prometheus:~$ curl -X POST -w "%{http_code}\n" --globoff 'http://localhost:9090/api/v1/admin/tsdb/delete_series?match[]={__name__=~"go_.*"}'
204

vagrant@prometheus:~$ curl -X POST -w "%{http_code}\n" http://localhost:9090/api/v1/admin/tsdb/clean_tombstones
204

当关注点主要围绕可伸缩性时,这些知识可能会帮助您控制本地存储并避免进入复杂且耗时的替代方案。

Remote storage integrations

选择远程度量存储不应该掉以轻心,因为它有几个含义。选择远程存储解决方案时需要考虑的一些因素(仅举几例)如下:

  • Maturity: Some storage solutions are more mature and better maintained than others.
  • Control: There are some solutions where you run your own instances, while others are SaaS offerings.
  • Availability, reliability and scalability: If you choose to manage the storage solution internally, you need to consider these aspects.
  • Maintainability: Some options are truly complex to deploy and/or maintain.
  • Remote read and write: Do you truly need both, or does write suffice for your use case?
  • Cost: It might all come down to this; we define cost not only in the monetary sense, but also in terms of the time required to learn, test, and operate a solution.

另一个需要考虑的关键因素与警报有关。为了可靠性,规则应该只查询本地数据;这可以防止网络层中的瞬时故障对规则评估产生负面影响。因此,远程存储系统中的数据不应该用于关键警报,或者至少您应该能够容忍它们丢失。

如果您使用的规模需要可扩展的存储,或者如果历史数据对您的用例至关重要,例如,对于容量规划,那么有几个选项可用。 Prometheus 官方文档有一个完整的已知远程存储集成列表,可在 https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage。此列表集成了几个不同的用例: SaaS 产品(例如 SignalFX 和 Splunk);流处理系统(Kafka);不同的时间序列数据库 包括付费 (IRONdb) 和开源(InfluxDB、Cortex、TimescaleDB、M3DB 等等);其他监控系统(OpenTSDB、Graphite);甚至是通用数据存储(例如 Elasticsearch 和 TiKV)。其中很大一部分支持远程读写。他们中的一些人应该拥有自己的一本书。

奇怪的是,在撰写本文时,我们将深入探索的解决方案不在上述列表中,因为它使用了一种完全不同的方法来解决我们正在处理的问题。事实上,Prometheus 甚至不需要知道它,因为它的工作原理就像一个叠加层。我们将专注于最有前途的长期存储解决方案,它完美地平衡了复杂性、成本和功能集:灭霸。

Thanos remote storage and ecosystem

第 13 章中,扩展和联合 Prometheus em>,我们被介绍给了 Thanos,这是一个开源项目,旨在大规模改进 Prometheus 的一些缺点。具体来说,我们了解了 Thanos 如何使用 Thanos sidecar 和查询器组件解决多个 Prometheus 实例的全局视图。现在是时候了解其他 Thanos 组件并探索它们如何协同工作以使用对象存储实现廉价的长期保留。请记住,沿着这条路走下去会增加复杂性,因此请验证您的要求以及全局视图方法和本地存储是否不足以满足您的特定用例。

Thanos ecosystem

除了我们之前介绍的 Thanos 查询器和 Sidecar 之外,Thanos 生态系统中还有一些其他组件。所有这些组件共存于同一个二进制文件中,并通过调用不同的子命令来运行,我们稍后会列举:

  • query: Commonly known as querier, it's a daemon that's responsible for fanning out queries and deduplicating results to configured StoreAPI endpoints
  • sidecar: A daemon which exposes a StoreAPI endpoint for accessing the data from a local Prometheus instance and ships the aforementioned instance's TSDB blocks to object storage
  • store: A daemon which acts as a gateway for remote storage, exposing a StoreAPI endpoint
  • compact: Commonly known as compactor, this daemon is responsible for compacting blocks that are available in object storage and creating new downsampled time series
  • bucket: A command line-tool that can verify, recover, and inspect data stored in object storage
  • receive: Known as receiver, it's a daemon that accepts remote writes from Prometheus instances, exposing pushed data through a StoreAPI endpoint, and can ship blocks to object storage
  • rule: Commonly known as ruler, it's a daemon that evaluates Prometheus rules (recording and alerting) against remote StoreAPI endpoints, exposes its own StoreAPI to make evaluation results available for querying, ships results to object storage, and connects to an Alertmanager cluster to send alerts
您可以在以下位置找到 Thanos 的所有源代码和安装文件 https://github.com/improbable-eng/thanos

以下所有组件协同工作以解决几个挑战:

  • Global view: Querying every Prometheus instance from the same place, while aggregating and deduplicating the returned time series.
  • Downsampling: Querying months or even years of data is a problem if samples come at full resolution; by automatically creating downsampled data, queries that span large time periods become feasible.
  • Rules: Enables the creation of global alerts and recording rules that mix metrics from different Prometheus shards.
  • Long-term retention: By leveraging object storage, it delegates durability, reliability, and scalability concerns of storage to outside the monitoring stack.

虽然我们将简要介绍灭霸如何应对这些挑战,但我们的主要关注点将放在它的长期存储方面。

在存储方面,Thanos 项目选择对象存储来存储长期数据。大多数云提供商都提供此服务,另外还可以确保为其提供服务级别协议 (SLA)。在任何顶级云提供商上,对象存储通常具有 99.999999999% 的持久性和 99.99% 的可用性。如果你有本地基础设施,还有一些可用的选项:使用 Swift(提供对象存储 API 的 OpenStack 组件),甚至是我们在本章测试环境中使用的 MinIO 项目。这些本地对象存储解决方案中的大多数都具有相同的特征: 它们提供的 API 被建模为模仿众所周知的 AWS S3,因为有很多工具支持它。此外,来自云提供商的对象存储通常是一种非常具有成本效益的解决方案。

下图简单概述了使用 Thanos 实现 Prometheus 时间序列数据的长期保留所需的核心组件:

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成
Figure 14.2: High-level Thanos long-term storage architecture

正如我们在上图中所见,我们只需要一些 Thanos 组件来应对这一挑战。在以下主题中,我们将介绍每个组件并扩展其在整体设计中的作用。

Thanos components

现在我们已经看到了 Thanos 长期存储架构的概述,是时候了解所有可用的 Thanos 组件了。除了介绍它们中的每一个之外,我们还将强调测试环境中可用的那些,扩展它们在生态系统中的作用,以及现有的配置。

You can find some community-driven alerts and dashboards at https://github.com/improbable-eng/thanos/tree/master/examples.

Test environment specifics

正如本书开头所述,使用提供的测试环境不会产生任何成本。因此,由于我们的示例需要一个对象存储桶,因此我们依赖于一个名为 MinIO 的项目,该项目公开了一个与 S3 兼容的 API; 您可以在 https://min.io/。配置方面,此存储端点应在具有以下设置的存储实例中可用:

vagrant@storage:~$ systemctl cat minio
...
EnvironmentFile=/etc/default/minio
ExecStart=/usr/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
...

前面的 systemd 单元文件加载了以下环境变量:

vagrant@storage:~$ sudo cat /etc/default/minio 
MINIO_VOLUMES='/var/lib/minio/data'
MINIO_OPTS='--address :9000'
MINIO_ACCESS_KEY='strongACCESSkey'
MINIO_SECRET_KEY='strongSECRETkey'

为确保您不必等待两个小时即可将块运送到对象存储中,我们测试环境中的 Prometheus 服务器具有以下设置:

vagrant@prometheus:~$ systemctl cat prometheus
...
    --storage.tsdb.max-block-duration=10m \
    --storage.tsdb.min-block-duration=10m
...

此配置更改块持续时间,设置将它们刷新到磁盘的时间间隔,从默认的两小时到十分钟。尽管设置如此低的值对于测试此特定功能非常有用,但对于其他任何事情都是完全不明智的。为了清楚地说明这一点,除了测试之外,没有充分的理由将这些值更改为两个小时以外的任何时间。

随着本章测试环境的细节,我们现在可以继续介绍每个单独的 Thanos 组件。

Thanos query

第 13 章中,扩展和联合 Prometheus em>,我们有机会探索了灭霸查询器和边车来解决全局视图问题。对于这个组件,我们随后介绍的特性也将在本章中使用。我们将继续使用 querier 来查询多个 StoreAPI 端点,利用它提供的重复数据删除功能,并通过其 Web 界面使用查询 API。

在我们的测试环境中可用的配置非常简单,我们可以在以下片段中看到,该片段取自 thanos 实例:

vagrant@thanos:~$ systemctl cat thanos-query
...
ExecStart=/usr/bin/thanos query \
            --query.replica-label replica \
            --store "prometheus:10901" \
            --store "thanos:11901" \
            --store "thanos:12901"
...

正如您在前面的代码片段中看到的,我们指定了几个 --store 端点。要了解哪个是哪个,我们可以将浏览器指向 Thanos 查询器 Web 界面,该界面位于 http://192.168.42.12 :10902/stores,并查看可用的商店,如下图所示:

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成
Figure 14.3: Thanos querier /stores endpoint

前面的屏幕截图展示了我们测试环境中所有可用的商店 API。这些将是您在 Thanos 查询器中执行查询时使用的数据源。

Thanos sidecar

除了我们之前介绍的 Thanos sidecar 公开的 Store API 之外,该组件还能够从磁盘收集 TSDB 块并将它们传送到对象存储桶。这允许您通过将历史数据保存在持久介质中来减少 Prometheus 服务器的保留。为了使用 sidecar 中的块上传功能,--storage.tsdb.min-block-duration--storage.tsdb.max-block-duration flags 需要设置为相同的值(两个小时以匹配默认行为),以便禁用 Prometheus 本地压缩。

正在使用的配置在 prometheus 实例上可用,可以通过执行以下指令进行检查:

vagrant@prometheus:~$ systemctl cat thanos-sidecar
...
ExecStart=/usr/bin/thanos sidecar \
           --log.level debug \
           --prometheus.url "http://localhost:9090" \
           --tsdb.path "/var/lib/prometheus/data" \
           --objstore.config-file "/etc/thanos/storage.yml"
...

正如我们所见,--objstore.config-file 标志从文件中加载所有必需的配置,以便将 TSDB 块发送到对象存储桶,例如桶名称(在我们的case、thanos)、存储端点和访问凭证。以下是该文件的内容:

vagrant@prometheus:~$ sudo cat /etc/thanos/storage.yml
type: S3
config:
  bucket: 'thanos'
  endpoint: 'storage:9000'
  insecure: true
  signature_version2: true
  access_key: 'strongACCESSkey'
  secret_key: 'strongSECRETkey'

在我们的 Prometheus 测试实例中,每 10 分钟将生成一个新的 TSDB 块,Thanos sidecar 将负责将其运送到对象存储端点。我们可以使用 MinIO 的 Web 界面查看存储桶中的可用块,该界面位于 http://192.168.42.11 :9000/minio/thanos/。使用前面代码片段中显示的 access_keysecret_key 登录后,您将看到类似于以下屏幕截图的内容:

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成
Figure 14.4: MinIO object storage web interface

我们现在应该有一些历史数据可用于测试。我们需要一种方法来查询这些数据。这就是灭霸商店网关发挥作用的地方。

Thanos store gateway

Thanos 存储网关的主要功能是提供对通过 StoreAPI 端点传送到对象存储的块中的历史时间序列数据的访问。这意味着它可以有效地充当 API 网关。 Thanos 存储(谷歌云存储、AWS S3、Azure 存储)中的所有主要对象存储集成都被认为足够稳定,可以在生产中运行。它使用所有块元数据的相对较小的本地缓存,并使其与存储桶保持同步。

在我们的测试环境中的 Thanos 实例中提供了该组件的最小配置。以下是其中的摘录:

vagrant@thanos:~$ systemctl cat thanos-store
...
ExecStart=/usr/bin/thanos store \
           --data-dir "/var/lib/thanos/store" \
           --objstore.config-file "/etc/thanos/storage.yml" \
           --grpc-address "0.0.0.0:11901" \
           --http-address "0.0.0.0:11902"
...

我们可以看到,对象存储配置是在它自己的配置文件中完成的。与大多数其他组件一样,存储绑定了一个用于接收查询的 StoreAPI GRPC 端口和一个 HTTP 端口,以便 Prometheus 可以收集其指标。

Thanos compact

由于需要关闭 Prometheus 块压缩才能使 Thanos 边车上传功能可靠工作,因此这项工作被委托给不同的组件:Thanos compact。它被设计为使用与 Prometheus 存储引擎本身相同的压缩策略,但用于对象存储中的块。由于压缩不能直接在对象存储中完成,因此该组件需要在本地磁盘中有相当数量的可用空间(几百 GB,取决于远程存储的数量)来处理块。

Thanos compact 执行的另一个重要功能是创建下采样样本。下采样的最大优势是可靠地查询大时间范围,而无需提取大量数据。 *_over_time 函数的使用(如 第 7 章 Prometheus 查询语言 PromQL)在使用下采样数据时也强烈推荐,因为用于下采样的方法不仅删除样本,而且预- 使用五种不同的聚合函数聚合它们。这意味着每个原始序列有五个新的时间序列。需要记住的非常重要的一点是,全分辨率数据仅在 40 小时后下采样到 5 分钟分辨率。类似地,一小时的下采样数据仅在 10 天后使用先前具有五分钟分辨率的下采样数据作为源创建。保留原始数据可能有助于及时放大特定事件,而仅使用下采样数据将无法做到这一点。有三个标志用于管理原始、五分钟和一小时形式的数据保留(即保留多长时间),如下表所示:

标记

持续时间

--retention.resolution-raw

持续时间将原始分辨率的数据保存在对象存储桶中,例如 365d(默认为 0d,表示永远)

--retention.resolution-5m

数据在对象存储桶中保留5分钟的时长,例如365d(默认为0d,表示永远)

--retention.resolution-1h

数据在对象存储桶中保存时间为 1 小时,例如 365d(默认为 0d,表示永远)

每个存储桶应该只有一个与之关联的 Thanos 压缩器,因为它不是为并发运行而设计的。

在考虑保留策略时,请记住,由于第一个下采样步骤聚合了 5 分钟的数据并且聚合产生了五个新的时间序列,因此您需要将抓取间隔设置为低于 1 分钟才能真正节省空间(间隔中的样本数需要高于聚合步骤产生的样本)。

压缩器既可以作为守护进程运行,在需要时立即执行,也可以作为单次作业,在运行结束时退出。在我们的测试环境中,我们在 thanos 实例中运行了一个 Thanos 压缩器来管理我们的对象存储桶。它作为服务运行(使用 --wait 标志)以简化测试环境。正在使用的配置显示在以下代码段中:

vagrant@thanos:~$ systemctl cat thanos-compact
...
ExecStart=/usr/bin/thanos compact \
           --data-dir "/var/lib/thanos/compact" \
           --objstore.config-file "/etc/thanos/storage.yml" \
           --http-address "0.0.0.0:13902" \
           --wait \
           --retention.resolution-raw 0d \
           --retention.resolution-5m 0d \
           --retention.resolution-1h 0d
...

就像其他组件一样,HTTP 端点对于从中抓取指标很有用。从 retention.* 标志中可以看出,我们将数据永久保存在所有可用的分辨率中。接下来我们将讨论 Thanos 存储桶,这是一种有助于检查 Thanos 管理的存储桶的调试工具。

Thanos bucket

Thanos 生态系统的这个组件负责验证、修复、列出和检查对象存储中的块。与其他组件不同,该组件充当命令行工具而不是守护程序。

您可以尝试以下使用示例:列出我们的对象存储桶中的可用块:

vagrant@thanos:~$ sudo thanos bucket ls -o wide --objstore.config-file=/etc/thanos/storage.yml
01D9SN3KEBNCB2MHASYXSDF1DE -- 2019-05-01 12:00 - 2019-05-01 12:10 Diff: 10m0s, Compaction: 1, Downsample: 0, Source: sidecar
01D9SNNXCAXWKZ0EH6118FTHSS -- 2019-05-01 12:10 - 2019-05-01 12:20 Diff: 10m0s, Compaction: 1, Downsample: 0, Source: sidecar
01D9SP87A9NZ9DE35TC2QNS7ZZ -- 2019-05-01 12:20 - 2019-05-01 12:30 Diff: 10m0s, Compaction: 1, Downsample: 0, Source: sidecar
01D9SPTH88G9TR4503C4763TDN -- 2019-05-01 12:30 - 2019-05-01 12:40 Diff: 10m0s, Compaction: 1, Downsample: 0, Source: sidecar
01D9SQCV68KVE7CXK4QDW9RWM1 -- 2019-05-01 12:40 - 2019-05-01 12:50 Diff: 10m0s, Compaction: 1, Downsample: 0, Source: sidecar
01D9SQN6TVJ97NP4K82APW7YH9 -- 2019-05-01 10:51 - 2019-05-01 11:50 Diff: 58m41s, Compaction: 2, Downsample: 0, Source: compactor

该工具对于排查问题和快速了解存储桶中块的状态非常有用。

Thanos receive

在撰写本文时,该组件仍处于试验阶段。然而,正如本章远程写入和读取部分所承诺的,这个组件是远程写入的一个很好的例子,所以我们决定向你展示它可以做什么。它充当 Prometheus 远程写入请求的目标,并将接收到的样本存储在本地。接收器还实现了一个 StoreAPI 端点,因此它能够充当存储节点。最后,它还可以像 sidecar 一样将块发送到对象存储。

为了更好地理解所有这些意味着什么,让我们探索两个场景。

默认情况下,Prometheus 服务器将每两个小时生成一个块。即使使用带有块传送的 Thanos sidecar,Thanos 查询器也无法获取仍在 WAL 中的数据,而 sidecar 必须通过 Prometheus 服务器的远程读取 API 请求它。当你达到 Grafana 或其他 API 客户端对 Prometheus 产生巨大请求率的规模时,它很可能会影响 Prometheus 的性能并最​​终影响警报,即使 Prometheus 有一些保护机制,正如我们所见之前。通过使用 Thanos 接收器,您可以简单地将客户端查询移至它,确保 Prometheus 服务器的主要工作是抓取和评估规则。简而言之,您将有效地将 Prometheus 服务器的读取与写入分开。您可以继续使用 Thanos sidecar 来发送块,使用 Thanos 接收器来回答所有 Thanos 查询器的查询,就像一个新的缓存一样,在此过程中保护 Prometheus 写入路径。

Thanos receiver generates blocks every two hours and, unlike Prometheus, this value is hardcoded by design.

想象另一种情况,其中有多个租户/团队使用您管理的基础架构。如果他们在技术上足够精通,他们最终会想要管理自己的 Prometheus 服务器。您可以尝试提供管理其服务器所需的所有自动化,但您很快就会遇到瓶颈。一种选择是给他们一个 Prometheus 服务器来管理、一个 Thanos 接收器端点和一个 Thanos 存储端点。 Thanos 接收器将负责将块运送到对象存储,而 Thanos 存储将提供一种访问它们的方法,从而完全从租户中抽象出远程存储的复杂性。这只是为您的基础架构提供长期存储即服务的第一步。

在我们的测试环境中,在 thanos 实例中,我们运行了一个 Thanos 接收器。在下面的代码片段中,我们可以看到它的配置:

vagrant@thanos:~$ systemctl cat thanos-receive
...
ExecStart=/usr/bin/thanos receive \
           --tsdb.path "/var/lib/thanos/receive" \
           --tsdb.retention 6h \
           --labels "store=\"receiver\"" \
           --remote-write.address "0.0.0.0:19291" \
           --grpc-address "0.0.0.0:12901" \
           --http-address "0.0.0.0:12902"
...

由于我们已经在 Prometheus 服务器旁边运行了一个 Thanos sidecar,它将 TSDB 块发送到对象存储,我们通过不添加 --objstore.config-file 标志来禁用接收器的传送功能.注意 --labels 标志,它允许我们指定一个标签以添加到此接收器的 StoreAPI 公开的所有时间序列中;这实际上是一种配置外部标签的方法。另一个值得注意的标志是--remote-write.address,用于提供远程写入端点。如果我们查看 prometheus 实例,我们将看到以下配置,它利用了上述标志:

vagrant@prometheus:~$ cat /etc/prometheus/prometheus.yml 
...
remote_write:
  - url: http://thanos:19291/api/v1/receive
...

为了测试所有这些,我们可以简单地在 prometheus 实例中停止 Thanos sidecar,如下所示:

vagrant@prometheus:~$ sudo systemctl stop thanos-sidecar

完成此操作后,Thanos 查询器将不再能够访问 Thanos sidecar,并且最近的块信息将不会刷新到磁盘。这样,我们可以验证接收方是否会提供这些数据。如果我们转到 http://192.168.42.12:10902/graph 的 Thanos 查询器 Web 界面,然后运行一个即时查询,例如 up{instance=~"prometheus.+"},我们会看到以下输出:

读书笔记《hands-on-infrastructure-monitoring-with-prometheus》将长期存储与普罗米修斯集成
Figure 14.5: Thanos receiver showing metrics, even with the Thanos sidecar down

注意 store 标签,表明 Thanos 接收器正在提供数据,同时还通知我们 Thanos sidecar 当前已关闭。这证明我们可以通过 Prometheus 远程写入 API 查询最近的数据。

使用这个组件的决定不应该掉以轻心,因为它有一些缺点:除了它被明确标记为实验性之外,它实际上是一个基于推送的系统,如 Graphite。这意味着基于推送的方法的所有缺点都适用,即难以管理滥用/流氓客户端。

Thanos rule

该组件允许您针对远程查询端点(例如 Thanos 查询器或 Sidecar)运行与 Prometheus 兼容的规则(记录/警报)。它公开了一个 StoreAPI 端点以使规则评估的结果可用,这些结果存储在本地块中,并且还可以将这些 TSDB 块发送到对象存储。很容易想象使用这个组件作为集中管理规则的解决方案,而不是将它们分散到多个 Prometheus 实例中,但这不是它的目的,而且是不明智的。在本书中,我们一直强调规则的重要性,尤其是对于警报。我们还强调了在具有所需指标的 Prometheus 实例中本地运行这些规则的重要性。我们提供了替代方案,例如分层或跨服务联合,用于从不同的 Prometheus 实例收集指标。通过使用 Thanos 标尺进行警报,您将在关键路径中添加许多故障点:其他 Thanos 组件、网络,以及最坏的情况下的对象存储。警报需要是可预测的和可靠的,因此您可以高度确信它会在您最需要的时候发挥作用。尽管灭霸统治者可以有一组合法的用例,但它不应该被考虑用于大多数警报需求。尽管如此,重要的是承认它的存在。

More information regarding the Thanos ruler can be found at https://thanos.io/components/rule.md.

我们现在对 Thanos 生态系统及其在测试环境中的配置有了一个完整的概述。我们邀请您在评估其行为的同时对所有组件进行试验:例如,停止除 Thanos 存储之外的所有存储 API,或使用 Thanos 存储桶了解对象存储存储桶中可用的数据。

Summary

在本章中,我们介绍了远程读取和远程写入端点。我们了解到最近使用 WAL 的远程写入策略对 Prometheus 的全局性能和可用性如此重要。然后,我们探索了一些控制 Prometheus 本地存储的替代方案,同时解释了选择长期存储解决方案的含义。最后,我们深入研究了灭霸,揭示了它的一些设计决策并介绍了完整的组件生态系统,提供了展示所有不同部分如何协同工作的实际示例。有了这个,如果需要,我们现在可以为 Prometheus 构建一个长期存储解决方案。

Questions

  1. What are the main advantages of a remote write based on WAL?
  2. How can you perform a backup of a running Prometheus server?
  3. Can the disk space of a Prometheus server be freed at runtime? If so, how?
  4. What are the main advantages of Thanos using object storage?
  5. Does it make sense to keep data in all available resolutions?
  6. What is the role of Thanos store?
  7. How can you inspect the data that's available in object storage using Thanos?

Further reading