存储
Prometheus 包含一个本地磁盘时间序列数据库,但也可选地与远程存储系统集成。
本地存储
Prometheus 的本地时间序列数据库以自定义、高效的格式存储在本地存储中。
磁盘布局
摄入的样本被分组为两小时的块。每个两小时的块包含一个目录,其中包含一个 chunks
子目录,该子目录包含该时间窗口的所有时间序列样本,一个元数据文件和一个索引文件(将指标名称和标签索引到 chunks
目录中的时间序列)。chunks
目录中的样本默认按一个或多个最大 512MB 的段文件分组。通过 API 删除序列时,删除记录存储在单独的 tombstone
文件中(而不是立即从数据块段中删除数据)。
当前用于传入样本的块保留在内存中,并且未完全持久化。它通过预写日志(WAL)来防止崩溃,当 Prometheus 服务器重新启动时可以重播此日志。预写日志文件存储在 wal
目录中,以 128MB 的段进行存储。这些文件包含尚未压缩的原始数据;因此它们比常规块文件大得多。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 和内存映射的块也计入总大小。因此,磁盘的最小要求是wal
(WAL 和 Checkpoint)和chunks_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 以四种方式与远程存储系统集成:
- Prometheus 可以将它摄入的样本以远程写入格式写入远程 URL。
- Prometheus 可以以远程写入格式从其他客户端接收样本。
- Prometheus 可以以远程读取格式从远程 URL 读取(回溯)样本数据。
- Prometheus 可以以远程读取格式将客户端请求的样本数据返回。
远程读写协议均使用 snappy 压缩的 HTTP 协议缓冲区编码。读协议尚未被视为稳定 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 小时(当前头部块)的数据是不安全的,因为这个时间范围可能与 Prometheus 仍在修改的当前头部块重叠。回填将创建新的 TSDB 块,每个块包含两小时的指标数据。这限制了块创建的内存需求。两小时块随后由 Prometheus 服务器本身压缩为更大的块。
一个典型的用例是将指标数据从不同的监控系统或时间序列数据库迁移到 Prometheus。为此,用户必须首先将源数据转换为 OpenMetrics 格式,这是下面描述的回填的输入格式。
请注意,此过程不支持原生直方图和陈旧标记,因为它们无法在 OpenMetrics 格式中表示。
使用方法
回填可以通过 Promtool 命令行使用。Promtool 会将块写入一个目录。默认情况下,此输出目录是 ./data/,您可以通过在子命令中使用所需输出目录的名称作为可选参数来更改它。
promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]
创建块后,将其移动到 Prometheus 的数据目录。如果与 Prometheus 中现有块存在重叠,对于 Prometheus v2.38 及以下版本,需要设置 --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
(对于 Prometheus v2.38 及以下版本,必须启用 --storage.tsdb.allow-overlapping-blocks
标志)。一旦移动,新块将在下次压缩运行时与现有块合并。
限制
- 如果您多次运行规则回填程序,并且起始/结束时间重叠,则每次运行规则回填程序时都会创建包含相同数据的块。
- 记录规则文件中的所有规则都将被评估。
- 如果在记录规则文件中设置了
interval
,则它将优先于规则回填命令中的eval-interval
标志。 - 如果告警位于记录规则文件中,目前会被忽略。
- 同一组中的规则无法查看先前规则的结果。这意味着不支持引用其他正在回填的规则。一个解决方法是多次回填并首先创建依赖数据(并将依赖数据移动到 Prometheus 服务器数据目录,以便可以通过 Prometheus API 访问)。