1. 什么是时序数据
时序数据(Time-Series Data) 是在时间上连续产生、且带有时间戳的观测值序列,典型特征:
维度 |
描述 |
高并发写 |
百万点/秒,追加为主 |
写多读少 |
90 % 查询是降采样或聚合 |
时效性 |
越新越热,旧数据价值递减 |
多维标签 |
每条点带大量 tag(设备、区域、指标名) |
示例:
cpu.usage{host=web01,region=bj} 2025-08-27 14:00:00 42.3
2. 时序数据库 vs 通用数据库
对比项 |
时序数据库 |
MySQL/PostgreSQL |
存储模型 |
列式 + 时间分区 |
B+Tree 行存 |
写入方式 |
LSM 追加 |
随机写 + WAL |
索引 |
倒排 + 时间线 |
B+Tree 复合索引 |
聚合算子 |
预计算、降采样 |
实时 GROUP BY |
压缩比 |
5--15× |
1--2× |
单节点吞吐 |
200--500 万点/秒 |
1--5 万点/秒 |
3. 适用场景与真实案例
行业 |
场景 |
规模示例 |
物联网 |
工业传感器、车联网 |
某车企 2000 万车机 × 100 指标/秒 |
金融 |
股票 Tick、风控日志 |
某券商 2 亿条/日 |
DevOps |
K8s 监控、APM |
某电商 50 万 Pod 指标/10 s |
能源 |
光伏逆变器、电网 PMU |
国家电网 60 TB/年 |
智慧城市 |
环境监测、灯杆数据 |
深圳 30 万设备/5 s |
4. 产品地图
4.1 开源
名称 |
语言 |
特点 |
InfluxDB |
Go |
TSM 引擎,Flux 查询,集群版闭源 |
TimescaleDB |
C/PostgreSQL |
扩展形式,SQL 完全兼容 |
VictoriaMetrics |
Go |
单二进制、PromQL、S3 冷存 |
OpenTSDB |
Java |
基于 HBase,PB 级 |
IoTDB |
Java |
面向工业场景,树形元数据 |
TDengine |
C |
超级表,边云同步 |
4.2 商业 & 云托管
- AWS Timestream 、Azure Data Explorer 、Google Cloud Bigtable + MDS
- InfluxDB Cloud 、Timescale Cloud 、Kdb+(高频交易)
5. 核心功能清单
功能 |
说明 |
示例 |
高吞吐写入 |
HTTP/Line Protocol |
InfluxDB curl -XPOST /write |
多维标签 |
任意键值对索引 |
cpu,host=web01,region=bj |
降采样 |
自动 Rollup |
CREATE CONTINUOUS QUERY |
数据保留策略 |
TTL + 分层 |
7 d 原始 / 1 y 5 min 均值 |
SQL & PromQL |
多语言查询 |
SELECT mean(value) FROM cpu GROUP BY time(1m) |
插值 & 外推 |
线性、前值填充 |
FILL(previous) |
订阅 & 告警 |
Webhook、Kafka |
kapacitor / vmalert |
数据压缩 |
Gorilla、Delta-of-Delta |
1.2 byte/point |
水平扩展 |
Sharding、Replication |
VictoriaMetrics VMCluster |
6. 技术原理六层拆解
6.1 数据模型
复制代码
┌---------┬-----------┬----------┐
│ timestamp │ value(float/int) │ tags(map[string]string) │
└---------┴-----------┴----------┘
- Series Key = measurement + tag set(字典序)
- Point = Series Key + timestamp + value
6.2 写入路径
复制代码
Client → Line Protocol → HTTP → WAL → MemTable → Immutable → SSTable(TSM/Chunk)
- WAL 顺序写,刷盘前宕机可重放
- MemTable 按 Series+Time 排序,刷盘后生成只读块
6.3 存储格式(以 InfluxDB TSM 为例)
复制代码
┌-------┬--------┬--------┐
│ Header │ Index Block │ Data Block │
└-------┴--------┴--------┘
- Index Block:Series → Offset 映射,二分查找
- Data Block :列式存储,timestamp & value 分开压缩
- 时间戳:Delta-Delta + RLE
- float:XOR (Gorilla)
- string:Snappy
6.4 倒排索引
- Tag → SeriesID List(类似 ES)
- 支持
AND / OR / NOT
组合
- 内存结构:Roaring Bitmap 压缩
- 持久化:TSI 文件,重启 mmap 恢复
6.5 查询执行
复制代码
1. Parse → Logical Plan
2. 根据 time range 过滤 Chunk
3. 根据 tag 过滤 Series
4. 并行扫描 → 预聚合
5. Merge → 排序 → 返回
- 预聚合(Continuous Aggregate)
CREATE MATERIALIZED VIEW ... WITH (timescaledb.continuous)
每 1 min 自动更新 1 min 均值,查询直接命中物化表。
6.6 压缩与降采样
- Gorilla:1.37 byte/point(官方论文)
- ZSTD:适合字符串 tag
- 降级策略 :
原始 1 s → 5 min 均值 → 1 h 均值 → 1 d 均值 → 归档 S3 → Glacier
7. 性能调优与最佳实践
维度 |
建议 |
模式设计 |
控制 tag 值基数 < 100 k,避免高基数 tag |
数据保留 |
使用 RP + 分区表,历史数据 detach 到对象存储 |
写入 |
批量 5k--10k 点 / req,开启 gzip 压缩 |
查询 |
使用预聚合、避免 SELECT * 原始数据 |
资源 |
内存 ≥ 倒排索引大小,SSD 存放热数据 |
监控 |
Prometheus + Grafana: |
influxdb_disk_bytes
vms_memory_usage
query_duration_seconds
|
案例:某直播公司
- 800 万 Series、200 万点/秒
- 单机 InfluxDB → 改为 VictoriaMetrics Cluster(3 存储 + 2 插入 + 2 查询)
- QPS ↑ 5×,磁盘 ↓ 60 %,P99 查询延迟从 2 s → 120 ms。
8. 未来趋势与总结
- Serverless + 对象存储:冷热分层到极致(Snowflake 模式)
- AI4DB:自适应压缩、索引推荐
- 流批一体:Flink + 时序库 → 实时降采样、异常检测
- 边缘协同:TDengine / IoTDB 边云同步,断网缓存
- 统一协议:OpenTelemetry、Arrow Flight SQL 成为事实标准
一句话总结
时序数据库用"顺序写、列式存、倒排索引、压缩算法、预聚合"五板斧,把"时间"这一维度变成了最大的性能红利;在 IoT、监控、金融等高并发场景,它是让"数据产生价值"的加速器,而不是简单的"又一个数据库"。