存储
Prometheus 包含一个本地磁盘时间序列数据库,但也支持与远程存储系统集成。
本地存储
Prometheus 的本地时间序列数据库以自定义的高效格式存储在本地存储中。
磁盘布局
摄入的样本被分组为两个小时的块。每个块包含一个目录,该目录中有一个 `chunks` 子目录,其中包含该时间窗口的所有时间序列样本,一个元数据文件和一个索引文件(该文件将度量名称和标签映射到 `chunks` 目录中的时间序列)。`chunks` 目录中的样本被组织成一个或多个段文件,每个文件默认最大为 512 MB。当通过 API 删除系列时,删除记录会存储在单独的墓碑文件中,而不是立即从块段中删除。
传入样本的当前块保存在内存中,并且不会完全持久化。通过写前日志(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
请注意,本地存储的一个限制是它不是集群化或复制的。因此,面对驱动器或节点故障时,它不能任意扩展或持久,并且应像任何其他单节点数据库一样进行管理。通过适当的架构,可以在本地存储中保留多年的数据。
推荐使用快照进行备份。不使用快照进行的备份有丢失自最后一个 TSDB 块创建以来记录的数据的风险,该块通常每两小时创建一次,覆盖最近三小时的样本。在备份或还原时排除 WAL 文件(`storage.tsdb.path` 中的 `chunks_head/`、`wal/` 和 `wbl/` 目录)将确保备份的一致性,但代价是会丢失 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 和 mmap 块也计入总大小。因此,磁盘的最低要求是 `wal`(WAL 和 Checkpoint)和 `chunks_head`(mmap 的 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 可以以远程读取格式 的形式向客户端返回请求的样本数据。

远程读写协议都使用 HTTP 上的 snappy 压缩协议缓冲区编码。读取协议尚未被视为稳定 API。
写入协议有一个1.0 版本的稳定规范和2.0 版本的实验性规范,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 中现有的块重叠,对于 v2.38 及更早版本的 Prometheus,需要设置标志 --storage.tsdb.allow-overlapping-blocks。请注意,任何回填的数据都将受到为您的 Prometheus 服务器配置的保留策略(按时间或大小)的约束。
更长的块持续时间
默认情况下,promtool 将使用默认块持续时间(2h)进行块处理;此行为是最普遍适用的且正确的。但是,当回填长时间数据时,使用更大的块持续时间值可能有利于更快地回填并防止 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 访问)。