TimescaleDB 基础教程
涵盖原理、架构、安装、最佳实践、常用场景、运维与性能优化。
TimescaleDB 是基于 PostgreSQL 的 时序数据库扩展,在保留 PostgreSQL 全功能的基础上,强化了时序数据的写入、查询、压缩、分区和生命周期管理能力。
它非常适合:
- 监控数据(Prometheus、Zabbix)
- IoT 设备数据
- 日志、指标、金融行情
- 工业时间序列数据
TimescaleDB 的底层逻辑只有两件事:
超表自动进行分区(chunks):
- 时间维度自动分片
- 空间维度可选(如 device_id、tenant_id)
- 高速写入优化
- 压缩 chunk
- 连续聚合(Continuous Aggregates)
- 数据自动清理、保留策略
- 时间序列函数(time_bucket、histogram 等)
⚠️ 本质仍然是 PostgreSQL,所以你所有 PostgreSQL 功能都能用(SQL、索引、备份、事务等)。
PostgreSQL
└── TimescaleDB Extension
├── Hypertable 管理
├── Chunks 分配与调度
├── 压缩引擎
├── Continuous Aggregates
├── Background Workers
└── Retention Policies
由于是扩展方式,TimescaleDB 可以做到:
- 不需要换数据库
- 不需要新的客户端协议
- 无学习成本
在 Debian/Ubuntu:
sudo apt install timescaledb-2-postgresql-17
在 PostgreSQL 中启用:
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE TABLE metrics (
time TIMESTAMPTZ NOT NULL,
device_id int,
value double precision,
tags jsonb
);
SELECT create_hypertable('metrics', 'time');
可选:按设备分区(空间维度分片)
SELECT create_hypertable('metrics', 'time', 'device_id');
| 场景 | chunk 时间间隔(推荐) |
|---|---|
| Prometheus 指标 | 1 天 |
| IoT 设备 | 1~7 天 |
| 交易行情/高频数据 | 1 小时 |
| 日志 | 1 天或 1 周 |
设置 chunk 大小约为 256MB ~ 1GB 最佳。
TimescaleDB 提供 列式压缩:
ALTER TABLE metrics SET (timescaledb.compress);
SELECT compress_chunk(i)
FROM show_chunks('metrics') as i;
自动压缩策略:
SELECT add_compression_policy('metrics', INTERVAL '7 days');
💡 常用:保留最近 7 天未压缩数据用于快速查询,老数据全部压缩。
压缩比可达 10x~30x。
类似“物化视图 + 自动增量更新”,非常适合:
- 按 1 分钟/5 分钟/1 小时聚合指标
- IoT 统计
- Dashboard 查询加速
示例:每 1 分钟求平均值
CREATE MATERIALIZED VIEW metrics_1m
WITH (timescaledb.continuous) AS
SELECT
time_bucket('1 min', time) AS bucket,
device_id,
avg(value) AS avg_value
FROM metrics
GROUP BY bucket, device_id;
自动刷新策略:
SELECT add_continuous_aggregate_policy(
'metrics_1m',
start_offset => INTERVAL '1 day',
end_offset => INTERVAL '1 min'
);
自动删除旧数据:
SELECT add_retention_policy('metrics', INTERVAL '90 days');
支持:
- 只删除未压缩数据
- 删除压缩 chunk
- 多表联动清理
常用函数:
| 函数 | 用途 |
|---|---|
| time_bucket() | 分组聚合,代替 date_trunc |
| time_bucket_gapfill() | 自动补齐时间空洞 |
| histogram() | 统计分布 |
| approx_percentile() | 高速百分位计算 |
| first() / last() | 高速查首尾值 |
示例:补齐缺失分钟
SELECT
time_bucket_gapfill('1 min', time),
avg(value)
FROM metrics
WHERE time > now() - interval '1 hour'
GROUP BY 1;
SELECT * FROM timescaledb_tune();
- 批量写入(COPY、批量 INSERT)
- 避免单行插入
- 自动分区减轻 IO 压力
通常只需要:
CREATE INDEX ON metrics (time DESC);
CREATE INDEX ON metrics (device_id);
- 控制在 256MB~1GB 左右
- 避免 chunk 过多(>5000 时会明显下降)
确保 chunk 小、VACUUM 快。
time TIMESTAMPTZ
device_id INT
value DOUBLE
metadata JSONB
metric
time
labels JSONB
value
| 特性 | TimescaleDB | InfluxDB | Prometheus |
|---|---|---|---|
| 底层 | PostgreSQL | 专有引擎 | 专有引擎 |
| SQL | ✅ 完整 SQL | ❌ Flux/SQL 变种 | ❌ PromQL |
| Join 查询 | ✅ | 不支持 | 不支持 |
| 持久化 | 强 | 弱 | 弱 |
| 集群 | PostgreSQL 自带方案 | 有商业版 | 无 |
| 压缩 | 强(10~30x) | 中 | 弱 |
总结:PostgreSQL 兼容性 + 时序性能 = TimescaleDB 最大优势。
最理想:
PostgreSQL 17 (带 TimescaleDB)
└── Patroni 高可用
├── etcd/consul
├── streaming replication
└── vip 或 haproxy 负载
TimescaleDB 的 scaling 方案:
| 功能 | 是否可行 |
|---|---|
| 水平扩展(多节点) | ✅(TimescaleDB multi-node) |
| 一主多从 | ✅ |
| 分表分区 | 自动 |
| 自动压缩 | ✅ |
| 自动冷热分层 | ✅ |