本节摘要:时序数据 90%+ 查询落在最近 48 小时,却常需保留 90 天至数年。TSDB 将热数据放 SSD/MemTable,温数据 compaction 后列存,冷数据进 S3/OSS 并可选降采样。Prometheus
--storage.tsdb.retention.time、Influx bucket RP、Timescale retention policy 与 Thanos/VictoriaMetrics 长期层各有一套语义——混用前须对齐。
阅读完本节,你应当能够:
用户要「10 年保留、每秒 10 万点、$0.01/GB/月」——长周期、高精度、低成本 构成不可能三角。Gorilla 浮点可压至 1.37 bits/point,但标签字符串难压;冷数据进对象存储便宜,跨层查询延迟陡增。VictoriaMetrics 实测:启用 ZSTD 后写入吞吐 降 37%,P99 查询延迟 降 62%——压缩与延迟的帕累托前沿无标准答案。
| 产品 | 热层 | 冷层 | Retention 配置 |
|---|---|---|---|
| Prometheus | 本地 TSDB 2h block | Thanos/VM/S3 | --storage.tsdb.retention.time |
| InfluxDB 2.x | shard hot | object store | bucket retentionRules |
| TimescaleDB | 最近 chunk on SSD | 旧 chunk detach → S3 | add_retention_policy |
| QuestDB | WAL + 当前分区 | 旧 partition drop | PARTITION BY DAY |
分层的前提是成本差异足够大,否则不值得架构复杂度。给一个粗略的量级对照(单位:元/GB/月,仅为量级示意):
| 层级 | 存储介质 | 典型成本 | 查询延迟 | 适合数据 |
|---|---|---|---|---|
| 热层 | NVMe SSD | 高 | 毫秒级 | 最近 48h |
| 温层 | 普通 SSD/HDD | 中 | 十毫秒~百毫秒 | 数周~数月 |
| 冷层 | S3/OSS | 低 | 秒级~分钟级 | 数月~数年 |
这就是「不可能三角」的化解方式:不是同时满足三者,而是让不同时期的数据各住各的档位。热层保证新鲜查询的体验,冷层控制长期保留的成本,中间用降采样进一步稀释冷层体积。
本地默认保留 15d(可调);remote_write 到 VictoriaMetrics/Cortex/Thanos Receive。查询长期数据走 Thanos Query 联邦本地与对象存储 block——本地只是「热缓存」,不是唯一真相源。
Bucket 绑定 retention period(如 30d)与 replication factor。过期 shard 整组删除;降采样 task 可写新 bucket 存 1y 聚合。
CREATE MATERIALIZED VIEW cpu_hourly WITH (timescaledb.continuous) AS SELECT time_bucket('1 hour', time) AS bucket, device_id, avg(cpu) FROM metrics GROUP BY bucket, device_id; SELECT add_retention_policy('metrics', INTERVAL '90 days'); SELECT add_retention_policy('cpu_hourly', INTERVAL '2 years');
raw 90d + hourly 2y 是常见 两级保留 模式。
| 算法 | 适用 | 权衡 |
|---|---|---|
| Gorilla XOR | 平滑 float metrics | 阶跃信号压缩差 |
| delta-of-delta | 等间隔时间戳 | 乱序写入需 reorder |
| ZSTD | VM/通用块 | 写入 CPU ↑,查询 ↓ |

| 场景 | 建议 |
|---|---|
| K8s 监控 | 本地 15–30d + VM 1y |
| 合规 7 年 | 冷 Parquet + 查询引擎 |
| IoT 海量 | 边缘 7d 聚合再上云 |
| 风控 tick | 热 QuestDB + 温 Timescale |
Retention 与 series 元数据:删 block 不删高基数 label 索引时,内存仍涨——需 relabel drop 与定期 /-/reload。
把数据放进对象存储后,查询会跨「本地区块 + 远端区块」两层:Thanos 需要从 S3 拉取索引与数据块,首查延迟轻松到秒级,冷层数据不适合做交互式 ad-hoc 分析。因此实践上有两条补充策略:一是在冷层上保留一份小时/日聚合(查询趋势用聚合,查询明细才碰原始块);二是给「跨 15 天以上的查询」设定超时与缓存,避免用户把冷层当热层用。这些约束要在设计时写清楚,而不是等线上慢查询爆发了再补。
设计或评审一套保留策略时,按下面五个问题逐项过,能避免大部分「保留半年后才发现成本失控」的尴尬:第一,合规上到底要求原始数据保留几年?合规与业务查询是两回事,很多场景只有审计需要原始数据,业务查询可以全部落在聚合层。第二,每个粒度的数据分别服务什么查询?交互式看板通常只看最近几天,月度报告看小时聚合,年度合规导出看日聚合。第三,降采样会丢什么精度?如果业务需要精确到秒的异常回放,降采样后的数据就无法支持,必须先保证原始层保留足够长。第四,冷层查询的延迟是否可接受?对象存储上的查询是秒级起步,任何「实时性」需求都不该放到冷层。第五,跨层数据一致性由谁保证?Thanos 的块对齐、Timescale 的 detach 时机、Influx 的分片删除,各自的边界必须写进运维手册。回答完这五个问题,保留策略就不再是拍脑袋的参数,而是一份有依据的工程决策。
⚠️ 常见坑:冷层查询跨 Thanos store 与 Prometheus 步长不一致——同比面板出现空洞。
💡 关键直觉:retention 是产品能力,不是 DBA 手工删表——选型时先看 bucket/chunk/policy 模型是否匹配合规年数。
下一章进入生态:OpenTelemetry 与集群容量规划。