
1) 【一句话结论】采用**时序数据库(TimescaleDB)+ 传统关系型数据库(MySQL)**的混合方案,核心时序数据按天分片存储,结合小时级预聚合表和Redis缓存热门查询,元数据通过CDC同步保证强一致性,并通过分片、预聚合、缓存优化实现秒级查询,同时明确数据一致性边界(库存数据允许1秒内延迟,元数据强一致)。
2) 【原理/概念讲解】
能源贸易的时序数据(价格、交易量、库存)核心是时间序列,查询多为时间范围聚合(如按小时查询价格走势)。传统关系型数据库(如MySQL)处理时间范围查询时,需复杂SQL(如窗口函数)且效率低;时序数据库(如TimescaleDB)专为时间序列设计,支持时间索引(快速定位时间窗口)、预聚合(提前计算统计量,如小时级平均价格),并按时间分片(如按天)实现水平扩展。预聚合表用于存储汇总数据(如按小时汇总价格、交易量),查询时优先从汇总表获取,减少实时表压力;Redis缓存热门时间范围查询(如最近1小时价格走势),设置动态TTL(根据访问热度调整,热门数据延长TTL),提升缓存命中率。元数据(品种、市场信息)存MySQL,通过CDC(如Debezium)同步,保证强一致性。类比:时序数据像按时间顺序排列的“流水线产品”,时序数据库是“时间切片仓库”,能快速按窗口取数据;关系型数据库是“产品说明书库”,管理规格,两者结合高效存储与查询。
3) 【对比与适用场景】
| 特性 | 时序数据库(TimescaleDB) | 传统关系型数据库(MySQL) |
|---|---|---|
| 定义 | 专为时间序列设计,支持时间索引、预聚合、自动分片 | 通用关系型数据库,支持复杂事务、ACID |
| 查询性能 | 优化时间范围查询,秒级聚合(时间索引+预聚合) | 处理时间范围查询效率低,需复杂SQL(如窗口函数) |
| 数据一致性 | 最终一致性(允许1-2秒延迟,适合时序场景) | 强一致性(事务,但时序查询慢) |
| 适用场景 | 实时监控、价格走势、库存变化(秒级查询) | 元数据管理(品种信息、用户权限、交易规则) |
| 注意点 | 分片后查询需路由,预聚合需定期更新 | 关联时序数据时需JOIN,影响性能 |
4) 【示例】
时序数据库(TimescaleDB)分片存储:按天分片,创建分片表(如存储2023-10-27数据)。
CREATE DATABASE energy_market;
CREATE TABLE price_data (
time TIMETZ NOT NULL,
product VARCHAR(50),
market VARCHAR(50),
price DECIMAL(10,2),
volume BIGINT,
inventory BIGINT,
PRIMARY KEY (time, product, market)
) WITH (timescaledb.compress = true, timescaledb.table_name = 'price_data_day_20231027');
INSERT INTO price_data (time, product, market, price, volume, inventory) VALUES ('2023-10-27 10:00:00+08', 'oil', 'shanghai', 60.5, 1000000, 5000000);
预聚合表(按小时汇总):
CREATE TABLE price_data_hourly (
bucket TIMETZ NOT NULL,
product VARCHAR(50),
market VARCHAR(50),
avg_price DECIMAL(10,2),
total_volume BIGINT,
PRIMARY KEY (bucket, product, market)
) AS
SELECT time_bucket('1 hour', time) as bucket,
product,
market,
AVG(price) as avg_price,
SUM(volume) as total_volume
FROM price_data
GROUP BY bucket, product, market;
Redis缓存热门查询:
SET price_trend_oil_shanghai_20231027_10_00_00 '{"time": "2023-10-27 09:00:00-10:00:00", "data": [{"time": "09:00", "price": 60.2}, ...]}' EX 300
MySQL存储元数据:
CREATE TABLE product_info (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
unit VARCHAR(20)
);
INSERT INTO product_info (product_id, product_name, unit) VALUES (1, '原油', '桶');
CDC同步:通过Debezium将时序数据写入MySQL,保证元数据一致性。
5) 【面试口播版答案】
面试官您好,针对海量时序数据的秒级查询需求,我建议采用混合数据库方案:核心时序数据用TimescaleDB按天分片存储,利用其时间索引和预聚合能力;元数据(品种、市场)存MySQL,通过CDC保证强一致;创建小时级预聚合表,查询时优先从汇总表获取;用Redis缓存热门时间范围查询(如最近1小时价格走势),设置动态TTL。这样既能实现秒级查询,又能管理元数据,同时通过分片、预聚合、缓存优化性能,并明确数据一致性边界(库存数据允许1秒内延迟,元数据强一致)。
6) 【追问清单】
如何处理每日10亿条数据的分片与扩展?
数据一致性如何保证?
如何优化秒级查询?
预聚合表如何更新?
7) 【常见坑/雷区】