你可能会安装 Prometheus,配置几个目标,然后让它运行数月而没有任何问题。然后有一天,/var/lib/prometheus 满了,Prometheus 拒绝启动,你发现一个充满编号文件夹的目录,却不知道它们是什么,也不知道是否可以安全删除它们。
在本章中,你将学习 Prometheus 将数据存储在何处,如何配置数据保留策略,TSDB 压缩的工作原理,以及如何在 Linux 上使用 Prometheus 创建和恢复数据库快照。
这些示例已在 Ubuntu 26.04 和 RHEL 9 上测试,但它们在运行 Prometheus 2.x 或 3.x 的任何最新 Linux 发行版上的工作方式相同。
Prometheus 如何在磁盘上存储数据
Prometheus 将其收集的所有指标存储在本地 时间序列数据库(TSDB) 中。该数据库专为高效存储带时间戳的指标数据而设计。
Prometheus 不会将每个指标直接保存到磁盘,而是先将新数据保存在内存和预写日志(WAL)中。大约每两小时,它会将这些数据写入磁盘上的一个永久性只读块。
如果你查看 Prometheus 数据目录内部,你会看到类似这样的内容:
ls -la /var/lib/prometheus/data
示例输出:
drwxr-xr-x 4 prometheus prometheus 4096 Jul 20 09:00 01J9ZK3XW9K7... drwxr-xr-x 4 prometheus prometheus 4096 Jul 20 11:00 01J9ZK5R2M4T... drwxr-xr-x 3 prometheus prometheus 4096 Jul 21 08:12 wal lrwxrwxrwx 1 prometheus prometheus 34 Jul 21 08:12 chunks_head -> 01J9ZKAB77Q2.../chunks
每个具有长名称的文件夹称为一个 块。一个块包含在特定时间段内收集的指标数据。在每个块内部,你会发现:
chunks/– 存储压缩后的指标样本。index– 将指标名称和标签映射到存储在 chunks 中的数据。meta.json– 包含有关块的信息,例如其时间范围和其他元数据。
wal 目录代表 预写日志。它在将新收集的指标写入 块 之前临时存储它们。这有助于防止在 Prometheus 意外停止时丢失数据。
chunks_head 链接指向尚未写入块的活动内存数据。
如果你注意到 wal 目录比平时增长得大得多,这通常意味着 Prometheus 无法足够快地创建新块。如果压缩延迟、磁盘 I/O 缓慢或 Prometheus 过载,可能会发生这种情况。
使用 promtool 检查块健康状况
在更改保留设置或创建备份之前,最好检查一下 TSDB 的健康状况。Prometheus 包含一个名为 promtool 的命令行工具,它提供了多个用于检查和排除数据库故障的命令。
要分析你的 TSDB,请运行:
promtool tsdb analyze /var/lib/prometheus
示例输出:
Block ID: 01J9ZK5R2M4TQXK9J8N3PZC7VW Duration: 2h0m0s Series: 48213 Label names: 62 Postings (unique label pairs): 1847
Series 值显示所分析块中存储了多少个唯一的时间序列。如果这个数字持续增加,即使受监控目标的数量没有改变,你可能存在 高基数 问题。
这通常发生在标签包含不断变化的值时,例如请求 ID、会话 ID、时间戳或客户端 IP 地址,导致 Prometheus 为每个唯一值创建一个新的时间序列。
其他一些有用的 promtool TSDB 命令包括:
1. 分析 TSDB
promtool tsdb analyze /var/lib/prometheus
显示诸如序列计数、标签基数和数据变更等信息,以帮助识别存储或性能问题。
2. 列出所有块
promtool tsdb list /var/lib/prometheus
显示每个块及其最小和最大时间戳。这对于检查是否有任何时间范围缺失很有用。
3. 从现有数据创建块
promtool tsdb list /var/lib/prometheus
从 OpenMetrics 数据或记录规则文件重建 TSDB 块。此命令主要用于导入或回填历史指标。
按时间和大小设置保留策略
Prometheus 会自动删除旧数据,但默认的保留设置可能与你拥有的磁盘空间量不匹配。你可以通过在启动 Prometheus 时设置保留选项来控制数据保留多长时间或允许 TSDB 使用多少磁盘空间。
如果你将 Prometheus 作为 systemd 服务运行,请创建或编辑一个覆盖文件:
sudo systemctl edit prometheus
你需要 sudo,因为 systemd 服务配置由 root 用户管理。
添加或更新以下行:
[Service] ExecStart= ExecStart=/usr/local/bin/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus \ --storage.tsdb.retention.time=15d \ --storage.tsdb.retention.size=10GB
其中:
--storage.tsdb.retention.time=15d将数据保留最多 15 天。--storage.tsdb.retention.size=10GB将 TSDB 限制为 10 GB 的磁盘空间。
如果同时设置了这两个选项,Prometheus 将应用先达到的那个限制。例如,如果数据库在数据达到 15 天 之前达到 10 GB,则会删除最旧的块以释放空间。
设置大小限制时,请留出一些可用磁盘空间,而不是使用整个分区。在压缩过程中,Prometheus 会在删除旧块之前临时写入新块,因此它需要额外的空间才能成功完成该过程。
保存更改后,重新加载并重启服务:
sudo systemctl daemon-reload sudo systemctl restart prometheus
要验证 Prometheus 是否已正确启动,请查看日志:
sudo journalctl -u prometheus -f
如果一切正常启动,你将看到指示 WAL 已加载且 TSDB 已成功启动的消息。
如果你收到数据目录的 权限被拒绝 错误,请确保 Prometheus 服务用户拥有该目录:
sudo chown -R prometheus:prometheus /var/lib/prometheus
然后再次重启服务。
压缩如何回收磁盘空间
Prometheus 在旧数据过期时不会立即释放磁盘空间。相反,它使用一个称为 压缩 的过程,将较小的块合并为较大的块,并删除已超过配置保留限制的数据。
新数据首先存储在两小时的块中。随着这些块变老,Prometheus 会将它们合并为覆盖更长时间范围的较大块。在此过程中,过期的数据将被永久删除。
这意味着删除抓取目标或从配置中删除指标不会立即减少磁盘使用量。旧数据保留在现有块中,直到这些块被压缩。根据你的保留设置和存储的数据量,可能需要几个压缩周期才能回收空间。
你可以通过查看 Prometheus 日志来检查压缩何时发生:
sudo journalctl -u prometheus | grep compact
示例输出:
level=info msg="compact blocks" count=3 mint=1721520000000 maxt=1721527200000 duration=4.2s
在此示例中:
count=3表示 Prometheus 将 三个现有块 合并为一个块。duration=4.2s表示压缩耗时 4.2 秒 完成。mint和maxt代表新块覆盖的最小和最大时间戳。
偶尔进行压缩是正常的。但是,如果你注意到压缩随着时间的推移花费的时间越来越长,这可能表明你的 Prometheus 服务器存储的时间序列比以前更多,或者磁盘性能正在成为瓶颈。
在这种情况下,请考虑增加存储容量、降低指标基数或降低保留设置。
在进行更改之前拍摄快照
在更改保留设置或执行维护之前,最好备份你的 TSDB。Prometheus 不像 MySQL 那样提供数据库转储,但它确实通过其 Admin API 支持 实时快照。快照可以在不停止 Prometheus 的情况下创建数据库的一致副本。
Admin API 默认是禁用的,因此你需要先启用它。编辑 Prometheus systemd 覆盖文件:
sudo systemctl edit prometheus
将以下选项添加到 ExecStart 行:
--web.enable-admin-api
保存文件,然后重新加载并重启 Prometheus:
sudo systemctl daemon-reload sudo systemctl restart prometheus
现在创建一个快照:
curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot
示例输出:
{
"status": "success",
"data": {
"name": "20260721T081204Z-8f2a91c3d4e5"
}
}
Prometheus 会在以下位置创建快照:
/var/lib/prometheus/snapshots/
将 <name> 替换为 API 返回的值,然后归档快照:
sudo tar -czf prometheus-backup-$(date +%F).tar.gz \ -C /var/lib/prometheus/snapshots \ <name>
该命令的作用如下:
tar -czf创建一个压缩的.tar.gz归档文件。-C /var/lib/prometheus/snapshots在创建归档之前切换到快照目录。<name>是 API 返回的快照目录。
将生成的归档文件复制到另一台服务器或外部存储,以便在本地磁盘故障时拥有备份。
恢复快照
要恢复备份,请先停止 Prometheus,以免它在您替换 TSDB 时尝试访问。
sudo systemctl stop prometheus
如果您是在现有安装上进行恢复,请先移动或删除当前的数据目录,以免与恢复的数据发生冲突。
将备份解压到 Prometheus 数据目录中:
sudo tar -xzf prometheus-backup-2026-07-21.tar.gz \ -C /var/lib/prometheus
然后重新启动 Prometheus:
sudo systemctl start prometheus
当 Prometheus 启动时,它会扫描数据目录,加载恢复的 TSDB 块,并像它们在本地创建的一样继续使用它们。如果您仅为创建快照而启用了 Admin API,最好在之后将其禁用。
从 systemd 覆盖文件中移除 --web.enable-admin-api 选项并重启服务。保持禁用状态可以减少 Prometheus 暴露的管理端点数量。
在 RHEL 和 Rocky Linux 上
在 RHEL 和 Rocky Linux 上,Prometheus 的配置和快照命令是相同的。主要区别在于 SELinux,如果数据目录没有正确的安全上下文,它可能会阻止 Prometheus 访问该目录。
如果您已将 TSDB 移动到新位置,请分配适当的 SELinux 上下文:
sudo semanage fcontext -a -t var_lib_t "/var/lib/prometheus(/.*)?" sudo restorecon -Rv /var/lib/prometheus
第一个命令告诉 SELinux 该目录应使用哪个上下文,第二个命令将该上下文应用于该目录及其所有内容。
如果 Prometheus 仍然无法启动,并且日志中包含诸如 Opening storage failed 的消息,但文件权限看起来正确,请检查最近的 SELinux 拒绝记录:
sudo ausearch -m avc -ts recent
如果输出显示对 Prometheus 数据目录的访问被拒绝消息,则表明 SELinux 正在阻止访问。在假设磁盘或 TSDB 本身存在问题之前,请先修复 SELinux 上下文。
常见错误及其含义
found (hash collision on unrelated labels) During Compaction:当两个不同的标签集产生相同的哈希值时,会出现此消息。虽然这种情况不常见,但 Prometheus 会在压缩期间自动处理它,通常不是问题。
除非该消息伴随其他存储错误,否则您无需修复任何内容。
即使设置了 retention.size,磁盘仍会填满:--storage.tsdb.retention.size 选项限制了存储的 TSDB 块的大小,但不包括 Write-Ahead Log(WAL)或仍在等待压缩的数据。
在大量收集指标期间,WAL 可能会增长到数 GB,然后其内容才会被写入块中。因此,不要将 retention.size 设置为等于磁盘的全部容量。至少留出 10–15% 的可用空间,以便 Prometheus 有足够的空间进行 WAL 增长和块压缩。
创建快照时出现 context deadline exceeded:如果您的 TSDB 很大或存储在较慢的磁盘上,创建快照所需的时间可能会超出客户端的预期。不要假设快照失败,而是增加 curl 请求的超时时间:
curl --max-time 120 -X POST \ http://localhost:9090/api/v1/admin/tsdb/snapshot
在许多情况下,即使客户端超时,快照仍会在服务器上继续运行,因此在重试之前请检查快照目录。
结论
您现在了解了 Prometheus 如何在其本地 TSDB 中存储指标、数据保存在磁盘上的位置,以及保留设置如何控制何时删除旧数据。
您还学习了压缩如何回收磁盘空间、如何使用 promtool 检查 TSDB,以及如何使用内置的 Admin API 创建和恢复快照。这些功能都内置于 Prometheus 中,因此您不需要任何额外的工具来管理或备份您的指标数据库。
作为快速检查,了解您的 Prometheus 服务器当前的配置:
ps aux | grep prometheus
查找 --storage.tsdb.retention.time 和 --storage.tsdb.retention.size 选项。如果两者均未设置,Prometheus 将使用其默认的保留行为,根据您收集的指标数量,这最终可能会填满您的磁盘。