时序数据库原理(TSDB)
时序数据库(Time Series Database,TSDB)是专门存储和时间相关数据的数据库系统。Prometheus、InfluxDB、TimescaleDB、Kdb+ 等都属于 TSDB 范畴。与传统关系型数据库相比,TSDB 针对时序数据的特性进行了专门优化,在写入吞吐、存储压缩、查询性能上都有数量级的优势。
理解 TSDB 的底层原理,有助于你在选型时做出正确判断,在使用时避免常见陷阱。
时序数据的特性
时序数据与普通业务数据有三个显著区别:
写入模式:高并发顺序写入,持续写入远多于随机写入和更新。传统数据库的 B+Tree 索引在高频写入场景下会产生大量随机 I/O,而 TSDB 采用 LSM-Tree 或专属的写入结构优化这一特性。
查询模式:范围查询为主,且通常是聚合查询(如「过去 1 小时的平均值」)。传统数据库的行式存储不适合这种「宽时间范围、窄返回结果」的查询模式,TSDB 采用列式存储或专属的时间分块索引。
数据生命周期:存在明显的「冷热」特性。最近的数据访问频繁,历史数据访问稀少但必须保留。TSDB 的数据分级存储和自动降采样,是针对这一特性的设计。
核心存储机制
Prometheus 采用的是基于内存的 Head Block + 基于磁盘的 mmap 混合存储。最新写入的数据先写入内存的 Head Block,当达到一定大小或时间阈值后,转换成 mmap 文件块(称为 Compacted Block)。磁盘上的 Block 是不可变的,这简化了并发控制。
Block 内部采用分段的内存映射文件(TSM,Time Structured Merge Tree)格式存储。每个 Block 的索引结构包含:Series 索引(标签 → 数据文件位置)、时间范围索引(时间 → 数据文件位置)、Bloom Filter(快速判断某个 Series 是否存在)。这种多级索引设计,使得即使数据量达到数 TB,查询仍然能在毫秒级完成。
查询执行优化
TSDB 的查询优化围绕「如何快速定位和读取数据」展开:
时间范围裁剪:查询时首先通过时间范围索引,只读取包含目标时间范围的数据块,避免全表扫描。
标签索引加速:通过倒排索引,根据标签条件快速找到匹配的 Series ID,再根据 Series ID 定位数据位置。
Streaming Aggregation:对于聚合查询(如 sum(rate(...))),采用流式计算模式,边读取数据边计算,无需将所有数据加载到内存。这对于大时间范围查询至关重要。