name: 使用时间序列数据库 description: 用于指标、物联网、金融数据和可观察性后端的时间序列数据库实现。适用于构建仪表板、监控系统、物联网平台或金融应用。涵盖TimescaleDB(PostgreSQL)、InfluxDB、ClickHouse、QuestDB、连续聚合、降采样(LTTB)和保留策略。
时间序列数据库
实现时间戳数据(指标、物联网传感器、金融报价、日志)的高效存储和查询。
数据库选择
基于主要用例选择:
TimescaleDB - PostgreSQL扩展
- 使用场景:已在PostgreSQL上,需要SQL + JOINs,混合工作负载
- 查询:标准SQL
- 规模:10万-100万插入/秒
InfluxDB - 专为时间序列设计
- 使用场景:DevOps指标、Prometheus集成、Telegraf生态系统
- 查询:InfluxQL或Flux
- 规模:50万-100万点/秒
ClickHouse - 列式分析
- 使用场景:需要最快的聚合、分析仪表板、日志分析
- 查询:SQL
- 规模:100万-1000万插入/秒,1亿-10亿行/秒查询
QuestDB - 高吞吐量物联网
- 使用场景:需要最高写入性能、金融报价数据
- 查询:SQL + Line Protocol
- 规模:400万+插入/秒
核心模式
1. 超级表(TimescaleDB)
自动基于时间的分区:
CREATE TABLE sensor_data (
time TIMESTAMPTZ NOT NULL,
sensor_id INTEGER NOT NULL,
temperature DOUBLE PRECISION,
humidity DOUBLE PRECISION
);
SELECT create_hypertable('sensor_data', 'time');
好处:
- 高效数据过期(删除旧块)
- 并行查询执行
- 旧块压缩(10-20倍节省)
2. 连续聚合
预计算汇总以快速仪表板查询:
-- TimescaleDB:小时级汇总
CREATE MATERIALIZED VIEW sensor_data_hourly
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 hour', time) AS hour,
sensor_id,
AVG(temperature) AS avg_temp,
MAX(temperature) AS max_temp,
MIN(temperature) AS min_temp
FROM sensor_data
GROUP BY hour, sensor_id;
-- 自动刷新策略
SELECT add_continuous_aggregate_policy('sensor_data_hourly',
start_offset => INTERVAL '3 hours',
end_offset => INTERVAL '1 hour',
schedule_interval => INTERVAL '1 hour');
查询策略:
- 短范围(最后一小时):原始数据
- 中范围(最后一天):1分钟汇总
- 长范围(最后一个月):1小时汇总
- 很长范围(最后一年):每日汇总
3. 保留策略
自动数据过期:
-- TimescaleDB:删除超过90天的数据
SELECT add_retention_policy('sensor_data', INTERVAL '90 days');
常见模式:
- 原始数据:7-90天
- 小时汇总:1-2年
- 每日汇总:无限保留
4. 可视化降采样
使用LTTB(最大三角形三桶)算法减少图表点数。
问题:浏览器无法平滑渲染100万点 解决方案:降采样到500-1000点,保持视觉保真度
-- TimescaleDB工具包LTTB
SELECT time, value
FROM lttb(
'SELECT time, temperature FROM sensor_data WHERE sensor_id = 1',
1000 -- 目标点数
);
阈值:
- < 1,000点:无降采样
- 1,000-10,000点:LTTB到1,000点
- 10,000+点:LTTB到500点或使用预聚合数据
仪表板集成
时间序列数据库是实时仪表板的主要数据源。
按组件的查询模式:
| 组件 | 查询模式 | 示例 |
|---|---|---|
| KPI卡片 | 最新值 | SELECT temperature FROM sensors ORDER BY time DESC LIMIT 1 |
| 趋势图 | 时间桶平均 | SELECT time_bucket('5m', time), AVG(cpu) GROUP BY 1 |
| 热力图 | 多指标窗口 | SELECT hour, AVG(cpu), AVG(memory) GROUP BY hour |
| 警报 | 阈值检查 | SELECT COUNT(*) WHERE cpu > 80 AND time > NOW() - '5m' |
数据流:
- 摄入指标(Prometheus、MQTT、应用事件)
- 存储到时间序列数据库,带连续聚合
- 应用保留策略(原始:30天,汇总:1年)
- 查询层降采样到最佳点数(LTTB)
- 前端使用Recharts/visx渲染
自动刷新间隔:
- 关键警报:1-5秒(WebSocket)
- 运维仪表板:10-30秒(轮询)
- 分析仪表板:1-5分钟(缓存)
- 历史报告:仅按需
数据库特定细节
实施指南见:
references/timescaledb.md- 设置、调优、压缩references/influxdb.md- InfluxQL/Flux、保留策略references/clickhouse.md- MergeTree引擎、集群references/questdb.md- Line Protocol、SIMD优化
降采样实施:
references/downsampling-strategies.md- LTTB算法、聚合方法
示例:
examples/metrics-dashboard-backend/- TimescaleDB + FastAPIexamples/iot-data-pipeline/- InfluxDB + Go for IoT
脚本:
scripts/setup_hypertable.py- 创建TimescaleDB超级表scripts/generate_retention_policy.py- 生成保留策略
性能优化
写入优化
批量插入:
| 数据库 | 批量大小 | 预期吞吐量 |
|---|---|---|
| TimescaleDB | 1,000-10,000 | 10万-100万行/秒 |
| InfluxDB | 5,000+ | 50万-100万点/秒 |
| ClickHouse | 10,000-100,000 | 100万-1000万行/秒 |
| QuestDB | 10,000+ | 400万+行/秒 |
查询优化
规则1:始终首先按时间过滤(索引化)
-- 差:全表扫描
SELECT * FROM metrics WHERE metric_name = 'cpu';
-- 好:使用时间索引
SELECT * FROM metrics
WHERE time > NOW() - INTERVAL '1 hour'
AND metric_name = 'cpu';
规则2:对仪表板查询使用连续聚合
-- 差:每次仪表板加载聚合10亿行
SELECT time_bucket('1 hour', time), AVG(cpu)
FROM metrics
WHERE time > NOW() - INTERVAL '30 days'
GROUP BY 1;
-- 好:查询预计算汇总
SELECT hour, avg_cpu
FROM metrics_hourly
WHERE hour > NOW() - INTERVAL '30 days';
规则3:可视化降采样
// 请求最佳点数
const points = Math.min(1000, chartWidth);
const query = `/api/metrics?start=${start}&end=${end}&points=${points}`;
用例
DevOps监控 → InfluxDB或TimescaleDB
- Prometheus指标、应用追踪、基础设施
物联网传感器数据 → QuestDB或TimescaleDB
- 数百万设备,高写入吞吐量
金融报价数据 → QuestDB或ClickHouse
- 亚毫秒查询,OHLC聚合
用户分析 → ClickHouse
- 事件追踪、每日活跃用户、漏斗分析
实时仪表板 → 任何TSDB + 连续聚合
- 预计算汇总、WebSocket流、LTTB降采样