prometheus数据持久化依托tsdb三层结构:head block负责毫秒级内存写入与实时查询,wal保障崩溃恢复,disk blocks实现不可变块文件存储与压缩清理,全程受retention、retentionsize等参数调控。

Prometheus 的数据持久化不是简单地把指标存到硬盘,而是围绕时间序列特性构建的一套精密协作机制。核心在于 TSDB 的分层设计:内存写入快、WAL 防丢、块文件稳、压缩降开销。
TSDB 的三层存储结构
TSDB 把数据生命周期拆成三个角色协同工作:
- Head Block(内存活跃区):所有新采集的样本首先进入这里,支持毫秒级写入和实时查询;它内部维护 active chunk,持续接收数据直到填满(默认2小时或120个样本),再触发刷新
- WAL(预写日志):每次写入 Head 前,先追加一条二进制日志到 WAL 文件;即使进程崩溃,重启时可通过回放 WAL 恢复未落盘的数据
- Disk Blocks(磁盘块):Head 刷新后生成不可变的块文件,每个块覆盖固定时间窗口(默认2小时),含索引、数据、删除标记三部分;老块会定期合并压缩,过期后自动清理
数据从采集到落盘的完整路径
一条指标从暴露端点到变成磁盘文件,经历清晰的阶段流转:
- 采集器(如 node_exporter)通过 HTTP 提供 /metrics 接口,Prometheus 主动拉取文本格式指标
- 服务端解析后,按 metric name + labels 组合定位唯一时间线,调用
Head.Append()写入内存 - 同步写入 WAL 文件,确保原子性与故障可恢复
- 当 active chunk 达限或定时触发(每2小时),将内存中该时间段数据序列化为 block 目录,含 meta.json、index、chunks 等子文件
- 后台 compaction 协程逐步合并小块为大块,提升查询效率并减少文件数量
影响持久化稳定性的关键配置
以下参数直接决定数据能否可靠保存、查得快、删得准:
-
retention:设置保留天数(如
15d),到期后整个 block 目录被标记删除;注意它控制的是“逻辑过期”,实际清理由后台任务执行 -
retentionSize:按磁盘空间设硬上限(如
"50GB"),比时间策略更可控,适合资源受限环境 - maxBlockDuration / minBlockDuration:调整块时间跨度,影响查询粒度与合并频率;大幅缩短可能增加小块数量,拖慢查询
- compaction.maxBlockSize:限制单个压缩后块的最大体积(默认2GB),防止过大块导致加载慢或 OOM
常见持久化问题与应对思路
实际运行中,几个典型现象背后都指向 TSDB 机制本身:
- 重启后数据“丢失”几秒?→ 检查 WAL 是否启用(默认开启),确认
storage.tsdb.wal-directory路径可写且未被清理 - 磁盘增长远超预期?→ 查看 block 数量与大小分布,可能是标签爆炸导致时间序列数激增,进而推高 Head 内存和 WAL 体积
- 查询变慢甚至超时?→ 观察是否大量小块未合并,或 retention 设置过长导致需扫描过多块;可临时调大
query.maxSamples并优化 PromQL 过滤条件 - OOM 频发?→ 内存占用 ≈ 活跃时间序列数 × 3KB + 块缓存;建议监控
prometheus_tsdb_head_series指标,结合storage.tsdb.retention.size控制规模











