存储

Prometheus 包含一个本地磁盘上的时间序列数据库,但也可以选择与远程存储系统集成。

本地存储

Prometheus 的本地时间序列数据库在本地存储上以一种自定义的高效格式存储数据。

磁盘布局

摄取的样本被分组为两小时的块。每个两小时的块都包含一个目录,其中包含一个 `chunks` 子目录,该子目录包含该时间窗口的所有时间序列样本、一个元数据文件和一个索引文件(将指标名称和标签索引到 `chunks` 目录中的时间序列)。`chunks` 目录中的样本被分组到一个或多个段文件中,默认每个文件最大为 512MB。当通过 API 删除序列时,删除记录会存储在单独的墓碑文件中(而不是立即从块段中删除数据)。

用于传入样本的当前块保存在内存中,并且没有完全持久化。它通过预写日志(WAL)来防止崩溃,当 Prometheus 服务器重新启动时可以重放该日志。预写日志文件以 128MB 的段存储在 `wal` 目录中。这些文件包含尚未压缩的原始数据;因此它们比常规块文件要大得多。Prometheus 将至少保留三个预写日志文件。高流量服务器可能会保留三个以上的 WAL 文件,以保持至少两小时的原始数据。

Prometheus 服务器的数据目录大致如下:

./data
├── 01BKGV7JBM69T2G1BGBGM6KB12
│   └── meta.json
├── 01BKGTZQ1SYQJTR4PB43C8PD98
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K
│   └── meta.json
├── 01BKGV7JC0RY8A6MACW02A2PJD
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── chunks_head
│   └── 000001
└── wal
    ├── 000000002
    └── checkpoint.00000001
        └── 00000000

请注意,本地存储的一个限制是它不是集群化或复制的。因此,它在面对驱动器或节点故障时不是任意可扩展或持久的,应该像任何其他单节点数据库一样进行管理。

建议使用快照进行备份。没有快照的备份存在丢失自上次 WAL 同步(通常每两小时发生一次)以来记录的数据的风险。通过适当的架构,可以在本地存储中保留多年的数据。

或者,可以通过远程读/写 API 使用外部存储。需要仔细评估这些系统,因为它们在持久性、性能和效率方面差异很大。

有关文件格式的更多详细信息,请参见 TSDB 格式 

压缩

最初的两小时块最终会在后台被压缩成更长的块。

压缩将创建更大的块,包含跨度长达保留时间 10% 或 31 天的数据,以较小者为准。

运维方面

Prometheus 有几个配置本地存储的标志。最重要的是:

  • --storage.tsdb.path:Prometheus 写入其数据库的位置。默认为 data/
  • --storage.tsdb.retention.time:样本在存储中保留多长时间。如果此标志和 storage.tsdb.retention.size 均未设置,则保留时间默认为 15d。支持的单位:y、w、d、h、m、s、ms。
  • --storage.tsdb.retention.size:要保留的存储块的最大字节数。最旧的数据将首先被删除。默认为 0 或禁用。支持的单位:B、KB、MB、GB、TB、PB、EB。例如:“512MB”。基于 2 的幂,所以 1KB 是 1024B。只有持久化块被删除以遵守此保留策略,尽管 WAL 和 m-mapped 块计入总大小。因此,磁盘的最低要求是 `wal`(WAL 和检查点)和 `chunks_head`(m-mapped Head 块)目录组合所占用的峰值空间(每 2 小时达到峰值)。
  • --storage.tsdb.wal-compression:启用预写日志 (WAL) 的压缩。根据您的数据,您可以期望 WAL 大小减半,而 CPU 负载增加很少。此标志在 2.11.0 版本中引入,并在 2.20.0 版本中默认启用。请注意,一旦启用,将 Prometheus 降级到 2.11.0 以下的版本将需要删除 WAL。

Prometheus 平均每个样本仅存储 1-2 字节。因此,要规划 Prometheus 服务器的容量,您可以使用粗略的公式:

needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample

要降低摄取样本的速率,您可以减少抓取的时间序列数量(更少的目标或每个目标更少的序列),或者您可以增加抓取间隔。然而,由于序列内样本的压缩,减少序列数量可能更有效。

如果您的本地存储损坏到 Prometheus 无法启动的程度,建议备份存储目录并从备份中恢复损坏的块目录。如果您没有备份,最后的手段是删除损坏的文件。例如,您可以尝试删除单个块目录或预写日志 (WAL) 文件。请注意,这意味着丢失这些块或 WAL 覆盖的时间范围内的数据。

注意Prometheus 的本地存储不支持非 POSIX 兼容的文件系统,因为可能会发生不可恢复的损坏。不支持 NFS 文件系统(包括 AWS 的 EFS)。NFS 可能是 POSIX 兼容的,但大多数实现不是。强烈建议使用本地文件系统以确保可靠性。

如果同时指定了时间和大小保留策略,则将使用首先触发的策略。

过期的块清理在后台进行。删除过期的块最多可能需要两个小时。块必须完全过期后才能被删除。

合理调整保留大小

如果您使用 storage.tsdb.retention.size 来设置大小限制,您需要考虑此值相对于为 Prometheus 分配的存储空间的合适大小。明智的做法是减小保留大小以提供一个缓冲,确保在 Prometheus 的分配存储空间满之前删除旧的条目。

目前,我们建议将保留大小设置为最多为分配给 Prometheus 的磁盘空间的 80-85%。这增加了在达到任何磁盘限制之前删除旧条目的可能性。

远程存储集成

Prometheus 的本地存储受限于单个节点的可扩展性和持久性。Prometheus 自身并不试图解决集群存储问题,而是提供了一组接口,允许与远程存储系统集成。

概述

Prometheus 通过四种方式与远程存储系统集成:

Remote read and write architecture

远程读写协议都使用基于 HTTP 的 snappy 压缩协议缓冲区编码。读取协议尚未被视作稳定 API。

写入协议有1.0 版本的稳定规范2.0 版本的实验性规范,Prometheus 服务器均支持。

有关在 Prometheus 中配置远程存储集成作为客户端的详细信息,请参阅 Prometheus 配置文档的远程写入远程读取部分。

请注意,在读取路径上,Prometheus 仅从远程端获取一组标签选择器和时间范围的原始序列数据。所有对原始数据的 PromQL 评估仍然在 Prometheus 本身中进行。这意味着远程读取查询存在一定的可扩展性限制,因为所有必要的数据都需要先加载到查询的 Prometheus 服务器中,然后在那里进行处理。然而,目前认为支持 PromQL 的完全分布式评估是不可行的。

Prometheus 也同时提供这两种协议的服务。内置的远程写入接收器可以通过设置 --web.enable-remote-write-receiver 命令行标志来启用。启用后,远程写入接收器端点为 /api/v1/write。远程读取端点可在 /api/v1/read 上使用。

现有集成

要了解更多关于与远程存储系统的现有集成,请参阅集成文档

从 OpenMetrics 格式回填

概述

如果用户希望从 OpenMetrics  格式的数据在 TSDB 中创建块,他们可以使用回填功能。但是,他们应该小心并注意,回填过去 3 小时(当前 head 块)的数据是不安全的,因为这个时间范围可能与 Prometheus 仍在修改的当前 head 块重叠。回填将创建新的 TSDB 块,每个块包含两小时的指标数据。这限制了块创建的内存需求。将两小时的块压缩成更大的块稍后由 Prometheus 服务器本身完成。

一个典型的用例是将指标数据从不同的监控系统或时间序列数据库迁移到 Prometheus。为此,用户必须首先将源数据转换为 OpenMetrics  格式,这是下面描述的回填的输入格式。

请注意,此过程不支持原生直方图和过时标记,因为它们无法在 OpenMetrics 格式中表示。

用法

回填可以通过 promtool 命令行使用。promtool 会将块写入一个目录。默认情况下,此输出目录是 ./data/,您可以通过在子命令中使用所需输出目录的名称作为可选参数来更改它。

promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]

创建块后,将其移动到 Prometheus 的数据目录。如果与 Prometheus 中现有的块有重叠,对于 v2.38 及以下版本的 Prometheus,需要设置 --storage.tsdb.allow-overlapping-blocks 标志。请注意,任何回填的数据都受 Prometheus 服务器配置的保留策略(按时间或大小)的约束。

更长的块持续时间

默认情况下,promtool 将使用默认的块持续时间(2小时)来创建块;这种行为是最普遍适用和正确的。然而,当回填长时间范围的数据时,使用更大的块持续时间值可能更有利,以便更快地回填并防止 TSDB 稍后进行额外的压缩。

--max-block-duration 标志允许用户配置块的最大持续时间。回填工具将选择一个不大于此值的合适块持续时间。

虽然更大的块可能会提高回填大型数据集的性能,但也存在缺点。基于时间的保留策略必须保留整个块,即使(可能很大的)块中只有一个样本仍在保留策略内。相反,基于大小的保留策略将删除整个块,即使 TSDB 只是轻微地超过了大小限制。

因此,用少数块进行回填,从而选择更大的块持续时间,必须谨慎进行,不建议用于任何生产实例。

为记录规则进行回填

概述

当创建新的记录规则时,没有它的历史数据。记录规则数据仅从创建时间开始存在。promtool 可以创建历史记录规则数据。

用法

要查看所有选项,请使用:$ promtool tsdb create-blocks-from rules --help

示例用法

$ promtool tsdb create-blocks-from rules \
    --start 1617079873 \
    --end 1617097873 \
    --url http://mypromserver.com:9090 \
    rules.yaml rules2.yaml

提供的记录规则文件应该是一个标准的 Prometheus 规则文件

promtool tsdb create-blocks-from rules 命令的输出是一个目录,其中包含记录规则文件中所有规则的历史规则数据块。默认情况下,输出目录是 data/。为了使用这些新的块数据,必须将这些块移动到正在运行的 Prometheus 实例的数据目录 storage.tsdb.path(对于 v2.38 及以下版本的 Prometheus,必须启用 --storage.tsdb.allow-overlapping-blocks 标志)。移动后,新的块将在下一次压缩运行时与现有块合并。

限制

  • 如果您多次运行具有重叠开始/结束时间的规则回填器,每次运行规则回填器时都会创建包含相同数据的块。
  • 记录规则文件中的所有规则都将被评估。
  • 如果在记录规则文件中设置了 interval,它将优先于规则回填命令中的 eval-interval 标志。
  • 如果告警在记录规则文件中,它们目前会被忽略。
  • 同一组中的规则无法看到先前规则的结果。这意味着不支持引用正在回填的其他规则的规则。一种解决方法是多次回填并首先创建依赖数据(并将依赖数据移动到 Prometheus 服务器数据目录,以便可以从 Prometheus API 访问)。

本页内容