2.4 时序数据库与指标存储


2.4 时序数据库与指标存储

本节摘要:监控指标本质上是一串带时间戳的序列,用普通关系数据库存既慢又贵。本节讲时序数据库(TSDB)为什么而生——写多读少、按时间组织、高压缩比——并解释它的基本存储模型与降采样策略,最后给你一个"什么时候上 TSDB、什么时候该换更大体系"的决策直觉。读完你能看懂一套指标存储的取舍逻辑。

为什么普通关系库存不住指标

如果你真的把监控指标存进 MySQL,会发现两个致命问题。第一是写入压力:监控指标是每秒都在产生的,一台稍大的集群就是每秒十万点上下,关系库以行锁和索引为中心的架构扛不住这种写密集。第二是查询模式不匹配:指标查询几乎总是"按时间范围拉一条序列",而你却要它做 B 树索引、行级去重——根本用不上关系库的强项,反倒被它的开销拖累。

时序数据库(Time Series Database,TSDB)专门为这种数据结构优化:先按时间分块,再用列式存储和压缩把存储成本打下来,这样既能扛住写密集,又能让"按时间范围取序列"这种查询跑得飞快。

一套指标在 TSDB 里长什么样

一套指标可以理解为四元组:指标名称 + 一组标签(labels) + 时间戳 + 值。比如"api 服务的 CPU 使用率 45",展开就是cpu_usage{host="api-01", dc="cn-north"} 45 @ 2026-09-01T03:00:00。其中 host 和 dc 就是标签维度,它们决定了你未来怎么聚合筛选。

TSDB 的存储核心思路是时间维度优先。它把数据按时间分成一个个 block,比如每两小时一个 block,block 内部再按标签做倒排索引、按列存储;写入时序数据时追加到当前活跃 block,满了就冻结、压缩、归并。这样查询时先按时间定位到 block,再在 block 里用标签索引快速捞序列,天然契合监控"以时间为主线"的访问方式。

为了把存储榨得更省,TSDB 普遍做两件事:

压缩:同一时间点的采样值差异往往不大,用 Delta 编码、字典编码、采样值对齐等手段压缩。一套设计良好的 TSDB 能把原始采样压掉一个数量级以上——同样十万个指标存一年,用对工具比用错工具省的空间差出好几倍。

降采样(Downsampling/转存):热数据保留全精度,老数据为了省空间,把时间分辨率从秒级降到分钟级、小时级,只保留聚合后的长周期趋势。值班人排查"上周三那次抖动"时并不需要秒级的原始值,分钟级就够了。降采样是控制存储成本的核心手段。

内存里的长周期查询为什么贵

TSDB 还有一个需要主动管理的点:长时间范围查询。拉一个"最近一年 CPU"的序列,如果原始采样是秒级、数据全在磁盘,聚合要扫的数据量惊人。所以大型体系通常配合长周期降采样 + 预聚合,把一年前这种老数据先降采样成小时级存好,查询直接读便宜的小序列,而不是每次都扫一年原始秒级点。

我见过有人把 Prometheus 单节点硬扛一年秒级数据,查询卡成十几秒没人敢点。教训就是:该上长周期降采样的没上,靠加大磁盘硬撑,看似省事,其实把查询体验和后期成本一起透支了。正确做法是提前规划热点周期,把历史数据按层次降采样落盘。

独立 TSDB vs 内嵌监控库 vs 托管云时序服务

选是你自己的决策,这里给三种典型路径:

  • 独立通用 TSDB(如 InfluxDB、VictoriaMetrics、TimescaleDB):可拔插、可对接多种监控后端,适合"既当指标库,又兼职业务时序计算"的场景。
  • 监控框架自带时序库(如 Prometheus 内置的存储):与框架深度整合、开箱即用,绝大多数中小集群首选,不用额外部署一套库。
  • 托管云时序服务(各云厂商的时序/监控服务):免运维、自带高可用,适合不想自己折腾存储的团队,代价是费用与供应商锁定。
存储路径 运维成本 灵活性 扩展性 适用规模
框架内置(Prometheus) 受单机限制 小型到中型
独立 TSDB 可横向 中型到大型
托管云时序服务 极低 弹性高 任意,看预算

我的倾向:单机集群别急着上重型 TSDB,Prometheus 内置存储 + 合理降采样完全够用;真要跨机房高可用、查询量大时,再去上独立 TSDB 或者托管服务。先用起来,别为存储造复杂度。

一个容量卡脖子的真实加班时刻

给你看一个我值班时反复碰到的问题:磁盘告警。现象是 Prometheus 所在数据盘满了,服务读盘卡顿。排查思路是三步走:

先把指标列表打开,看哪些是"大头"——往往是一类高基数标签(比如每个用户 ID 都当了标签),基数爆炸直接让倒排索引和压缩失效。第二,砍掉没必要的高基数标签,把用户级维度换成业务聚合维度;第三,给高频写入的序列开启降采样,老数据降分辨力。三步做完,数据盘从 90% 掉回 40%。这类"存储被高基数吃光"的坑,本质是指标设计的问题,不是扩容能根治的——扩了盘,下个月还会吃光。

高基数问题值得再挖一层

上面提到高基数是存储杀手,值得说透它的机理。所谓基数(cardinality),就是某个标签维度下取值组合的种数。一个 user_id 标签如果有十万个用户,那一套指标就会被拆成十万条独立的序列。倒排索引、压缩、查询全部跟着放大——压缩失效就是因为字典编码在十万个几乎互不相同的取值上无从下手。所以指标设计有一条铁律:标签只放能用于筛选和聚合的稳定维度(host、dc、服务名、接口名),绝不放会爆炸的实体 ID。真需要按用户看,把它放进日志或业务库,别绑进指标库。

另外,基数问题还与"抓取目标数量"耦合:Prometheus 每两小时一个 block,block 内序列越多,活跃内存越大,往往不必等磁盘满,先被内存吃掉。排查时除了看磁盘,还要盯 active series 数量这条线——它才是高基数爆发的第一预警。

本节要点回顾

  • TSDB 为什么而生:写多、按时间组织、高压缩比,关系库扛不住。
  • 指标四元组:名称 + 标签 + 时间戳 + 值,标签决定聚合能力。
  • 时间优先存储:按 block 分块 + 标签索引 + 列式存储。
  • 压缩与降采样:控制成本的两大王牌,老数据降分辨力。
  • 长周期预聚合:让一年前的查询读便宜序列,不扫原始秒级点。
  • 高基数是存储杀手:用户级标签爆炸会让压缩失效,先改指标设计。
  • 选路三杯茶:先内置,再独立 TSDB,规模大或图省心上托管。

数据存进来了,下一步是把它们变成人能一眼看懂的仪表盘。下一节讲仪表盘设计——布局、焦点、告警缓放,这三件事做对了,面板才真能给你三秒定位问题的能力。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U