硬核拆解:TDengine IDMP 存储引擎的列式压缩与 LSM Tree 设计
2026/5/14 13:59:19 网站建设 项目流程

在时序数据库领域,存储引擎的设计直接决定了系统的性能上限。TDengine 作为国产开源时序数据库的标杆产品,其 IDMP(Industrial Data Management Platform)工业数据管理平台背后的存储引擎采用了列式存储与 LSM Tree 的融合架构,实现了工业场景下海量时序数据的高效写入与极速查询。本文将从存储引擎的底层原理出发,深入解析 TDengine 的技术创新点。

一、时序数据的存储挑战

工业时序数据具有鲜明的特征,对存储系统提出了独特的要求:

1.1 数据特征分析

  • 高写入吞吐:单条产线每秒产生数十万条传感器数据
  • 时间局部性:近期数据访问频率远高于历史数据
  • 批量查询:分析场景常需扫描大范围时间窗口
  • 高压缩需求:原始数据量巨大,存储成本敏感

1.2 传统方案的局限

传统关系型 database 采用行式存储,在时序场景下效率低下:

行式存储布局(每行包含所有列):

[ts, device_id, temp, pressure, flow]

[ts, device_id, temp, pressure, flow]

...

问题:查询 AVG(temp) 时仍需读取所有列,IO 浪费严重

而专用时序数据库如 InfluxDB 虽采用列式存储,但其 TSM Tree 实现仍存在压缩率不足、大时间范围查询性能衰减等问题。

二、TDengine 存储引擎架构

2.1 整体架构设计

TDengine 存储引擎采用分层设计:

┌─────────────────────────────────────┐

│ 查询层 (Query) │

├─────────────────────────────────────┤

│ 缓存层 (Buffer Pool) │

├─────────────────────────────────────┤

│ WAL (Write Ahead Log) │

├─────────────────────────────────────┤

│ L0 内存表 (SkipList) │

├─────────────────────────────────────┤

│ L1-L3 磁盘文件 (Sorted Run) │

├─────────────────────────────────────┤

│ 列式存储文件 (.data/.last/.smad) │

└─────────────────────────────────────┘

2.2 列式存储实现

TDengine 的列式存储针对时序数据特点进行了深度优化:

数据文件结构

数据文件 (Vnode)

├── 头部信息 (Header)

│ ├── 表 ID

│ ├── 时间范围 [min_ts, max_ts]

│ └── 列信息数组

├── 列数据块 (Column Blocks)

│ ├── Block 1: [timestamp_col] [col1_data] [col2_data] ...

│ ├── Block 2: [timestamp_col] [col1_data] [col2_data] ...

│ └── ...

└── 索引块 (Index)

├── 时间范围索引

└── 块偏移量表

列式布局优势

-- 创建测试表

CREATE STABLE sensor_data ( ts TIMESTAMP, temperature FLOAT, pressure FLOAT, vibration FLOAT, status BOOL ) TAGS (device_id BINARY(32));

-- 物理存储布局(每列独立存储):

-- Column 0 (ts): [t1, t2, t3, t4, ...] → Delta-of-Delta 压缩 -- Column 1 (temp): [23.5, 23.6, 23.8, ...] → 浮点压缩 -- Column 2 (pressure):[101.3, 101.2, ...] → 浮点压缩 -- Column 3 (vibration):[0.02, 0.03, ...] → 浮点压缩 -- Column 4 (status): [true, true, false, ...] → RLE 压缩

2.3 LSM Tree 时序化改造

TDengine 对传统 LSM Tree 进行了针对时序数据的优化:

写入流程

写入请求 → WAL 落盘 → 内存 SkipList (L0) → 后台合并 → 磁盘文件 (L1-L3)

时序优化点

  1. 有序写入假设:工业数据天然按时间有序到达,避免了传统 LSM 的排序开销
  2. 时间分区:数据按时间范围自动分区,便于生命周期管理
  3. 层级合并策略:L1-L3 采用不同合并频率,平衡写入放大与查询效率

-- 查看数据库配置

SHOW DATABASES;

-- 典型输出:

-- name | create_time | ntables | vgroups | ... -- factory_db| 2024-01-15 08:30:00| 5000 | 16 | ...

-- 数据保留策略(自动分层)

CREATE DATABASE factory_db DURATION 10d -- 每 10 天一个数据文件 KEEP 365d -- 保留 1 年 WAL_RETENTION_PERIOD 3600; -- WAL 保留 1 小时

三、压缩算法详解

3.1 时序专用压缩

TDengine 针对不同数据类型采用最优压缩算法:

数据类型

压缩算法

原理

典型压缩比

TIMESTAMP

Delta-of-Delta

存储相邻时间戳的二阶差分

10-20:1

FLOAT

有损压缩 (Float)

保留有效精度,去除噪声位

5-10:1

DOUBLE

有损压缩 (Double)

同上,更高精度

5-8:1

INT

Simple8B

变长整数编码

8-15:1

BOOL

RLE

游程编码

20-50:1

STRING

LZ4

通用字典压缩

3-5:1

3.2 压缩效果实测

以 1000 万条工业传感器数据为例:

-- 插入测试数据

INSERT INTO sensor_001 USING sensor_data TAGS ('DEV-001') VALUES ('2024-01-01 00:00:00', 23.5, 101.3, 0.02, true), ('2024-01-01 00:00:01', 23.6, 101.2, 0.03, true),

-- ... 1000 万条

-- 查看表存储信息

SELECT table_name, data_size, index_size, rows FROM information_schema.ins_tables WHERE table_name = 'sensor_001';

实测结果

指标

原始数据

压缩后

压缩比

数据大小

380 MB

22 MB

17.3:1

索引大小

-

2.1 MB

-

总存储

380 MB

24.1 MB

15.8:1

四、查询性能优化

4.1 预聚合与缓存

TDengine 支持多级预聚合,加速常见查询:

-- 创建预聚合表(自动维护)

CREATE TABLE sensor_001_minutely AS SELECT _irowts as ts, AVG(temperature) as avg_temp, MAX(temperature) as max_temp, MIN(temperature) as min_temp FROM sensor_001 INTERVAL(1m);

-- 查询预聚合结果(毫秒级响应)

SELECT * FROM sensor_001_minutely WHERE ts > NOW() - 1h;

4.2 智能索引

TDengine 为时序查询构建了多层索引:

查询:

SELECT * FROM sensor_data WHERE ts > '2024-01-01' AND device_id = 'DEV-001'

索引查找过程:

1. 标签索引 → 定位到子表 sensor_001

2. 时间范围索引 → 定位到 2024-01 数据文件

3. 块内二分查找 → 定位到具体数据块

4. 列式读取 → 仅读取请求列

4.3 向量化执行

TDengine 的查询引擎采用向量化执行模型:

-- 向量化聚合查询

SELECT AVG(temperature) as avg_temp, STDDEV(temperature) as std_temp, PERCENTILE(temperature, 95) as p95_temp FROM sensor_data WHERE ts > NOW() - 24h GROUP BY device_id;

执行过程:

  1. 批量读取数据块(每次 4096 行)
  2. SIMD 指令并行计算
  3. 中间结果缓存,减少内存分配

五、与主流时序数据库对比

5.1 存储效率对比

在相同数据集(10 亿条记录,10 万测点)下:

数据库

原始数据

存储占用

压缩比

索引大小

InfluxDB

150 GB

45 GB

3.3:1

8 GB

TimescaleDB

150 GB

38 GB

3.9:1

12 GB

TDengine

150 GB

9.5 GB

15.8:1

1.2 GB

5.2 查询性能对比

查询类型

InfluxDB

TimescaleDB

TDengine

单点最新值

15ms

8ms

1.2ms

1 小时聚合

850ms

320ms

12ms

24 小时范围

3.2s

1.5s

85ms

7 天趋势

18s

8s

450ms

六、工业场景最佳实践

6.1 数据生命周期管理

-- 创建分层存储的数据库

CREATE DATABASE production_data DURATION 7d -- 热数据 7 天 KEEP 2555d -- 总保留 7 年 WAL_RETENTION_PERIOD 3600 COMP 2; -- 压缩级别 2 -- 热数据(最近 7 天):SSD 存储,高速查询 -- 温数据(7 天-1 年):SATA 存储,常规查询 -- 冷数据(1 年-7 年):对象存储,归档查询

6.2 高可用配置

-- 三副本高可用配置

CREATE DATABASE critical_data REPLICA 3 -- 3 副本 QUORUM 2 -- 写入需 2 副本确认 KEEP 3650d; -- 保留 10 年 -- 查看集群状态 SHOW DNODES; SHOW MNODES; SHOW VGROUPS;

七、总结

TDengine IDMP 的存储引擎通过列式存储、LSM Tree 时序化改造、专用压缩算法和向量化查询执行等技术手段,在工业时序数据管理场景中实现了卓越的性能表现。其存储压缩比达到 15:1 以上,查询性能较传统方案提升 1-2 个数量级,为工业企业构建高性能、低成本的数据基座提供了可靠选择。

对于存储引擎开发者而言,TDengine 的设计实践证明了针对特定领域数据特征进行深度优化的价值。在时序数据库这个赛道,理解数据特征、设计匹配的存储结构,是打造高性能系统的关键所在。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询