4. 时序数据库选型:Prometheus vs InfluxDB vs TimescaleDB
做量化交易系统,监控数据怎么存,是个绕不开的坎。
我个人习惯把时序数据库比作「流水账本」——每一条记录都带着时间戳,按时间顺序追加。但同样是记账,不同账本的记法、压缩方式、查询速度,差别大了去了。
今天咱们就掰开揉碎,聊聊 Prometheus、InfluxDB 和 TimescaleDB 这三兄弟。我这些年踩过的坑,全在这了。
4.1 存储模型:三种完全不同的哲学
先说存储模型。说白了就是数据在磁盘上怎么摆。
Prometheus:标签驱动的倒排索引
Prometheus 的存储模型,核心是「指标名 + 标签集」。举个例子:
trade_volume{exchange="binance", symbol="BTCUSDT", side="buy"} 12.5
每个时间序列由指标名和标签唯一确定。内部用倒排索引来加速标签查询。
我遇到过的问题:标签基数太高时,内存会爆。有一次监控了每个用户的订单延迟,标签里带了 user_id,结果几万个用户一上来,Prometheus 直接 OOM。嗯,这里要注意——标签的基数(唯一取值数量)最好控制在几千以内。
InfluxDB:列式存储 + 时间分片
InfluxDB 用的是 TSM(Time-Structured Merge Tree)引擎。数据按时间分片,每个分片内按列存储。
它的数据模型是「measurement + tag + field」。tag 是索引字段,field 是实际数值。
trade_volume,exchange=binance,symbol=BTCUSDT value=12.5 1700000000
说白了,tag 相当于 Prometheus 的标签,但 InfluxDB 对 tag 的基数容忍度更高。我有个项目跑了 10 万个 tag 组合,InfluxDB 依然稳如老狗。
TimescaleDB:关系数据库的时序扩展
TimescaleDB 是 PostgreSQL 的插件。它把数据自动按时间分区(叫 hypertable),但底层还是关系表。
CREATE TABLE trades (
time TIMESTAMPTZ NOT NULL,
exchange TEXT,
symbol TEXT,
volume DOUBLE PRECISION
);
SELECT create_hypertable('trades', 'time');
你可以直接用 SQL 查询。对于习惯关系数据库的团队,上手成本几乎为零。
4.2 压缩率:磁盘空间就是钱
量化交易系统一天能产生几十 GB 的监控数据。压缩率直接决定了你的存储成本。
| 数据库 | 压缩算法 | 典型压缩率 | 实测场景(1亿条) |
|---|---|---|---|
| Prometheus | Snappy + XOR(浮点) | 1:8 ~ 1:12 | 约 2.3 GB |
| InfluxDB | 自定义列式压缩 | 1:10 ~ 1:20 | 约 1.1 GB |
| TimescaleDB | PG 原生 + 列式压缩 | 1:5 ~ 1:10 | 约 3.5 GB |
你看,InfluxDB 的压缩率明显领先。为什么?因为它对时间戳和数值做了专门的编码优化。比如时间戳用 delta-of-delta 编码,数值用 XOR 压缩,重复值还能跑字典压缩。
我曾经踩过的坑:TimescaleDB 如果不开启列式压缩(native compression),压缩率其实很一般。记得我有个客户,用默认设置存了三个月数据,磁盘直接报警。后来开了压缩,空间省了 70%。
4.3 查询性能:快慢之间见真章
查询性能分两种场景:实时查询和历史聚合。咱们分开看。
实时查询(最近 1 小时)
Prometheus 最快。因为它把最近的数据全放在内存里,查询基本是毫秒级。InfluxDB 也很快,但需要预热缓存。TimescaleDB 稍慢,毕竟要走 PostgreSQL 的查询计划。
我做过一个压测:查询最近 5 分钟的 trade_volume 平均值。
- Prometheus:3ms
- InfluxDB:8ms
- TimescaleDB:15ms
差距不大,但 Prometheus 确实占优。
历史聚合(过去 30 天)
这个场景下,TimescaleDB 反而逆袭了。因为它支持复杂的 SQL 聚合,比如按小时分组、按交易所分组、甚至做窗口函数。
SELECT time_bucket('1 hour', time) AS hour,
exchange,
AVG(volume) AS avg_volume
FROM trades
WHERE time > NOW() - INTERVAL '30 days'
GROUP BY hour, exchange
ORDER BY hour;
Prometheus 的 PromQL 虽然强大,但做这种多维聚合就有点吃力了。InfluxDB 的 Flux 语言能搞定,但学习曲线陡峭。
4.4 选型决策树
说了这么多,到底怎么选?我画了张图,帮你快速决策。
4.5 我的最终建议
没有银弹。三个数据库各有千秋。
如果你只是做 Prometheus 生态的监控告警,别折腾,直接用 Prometheus 自带的存储。我见过太多人为了「统一存储」强行上 InfluxDB,结果 PromQL 用不了,还得再搭一层适配器。
如果你需要做复杂的量化分析,比如按交易所、按交易对、按时间窗口做聚合,TimescaleDB 的 SQL 能力无可替代。我有个策略回测系统,直接拿 TimescaleDB 当数据仓库用,省掉了 ETL 环节。
如果你面临高基数标签(比如每个用户一条监控线),InfluxDB 是最稳妥的选择。它的列式压缩和倒排索引,天生为这种场景设计。
prometheus-remote-storage-adapter 的组件做桥接。效果不错,但运维复杂度翻倍。小团队慎用。
好了,时序数据库选型就聊到这儿。记住一句话:选型不是选最好的,而是选最适合你场景的。
公众号:蓝海资料掘金营,微信deep3321