TDengine时序数据库压缩算法与存储成本优化

Xiaxin Li

2026-05-28 /

时序数据库作为物联网、工业互联网和金融交易等领域的核心基础设施,面临着海量数据存储的巨大挑战。TDengine作为一款专为时序数据设计的高性能数据库,通过创新的多级压缩技术,将存储成本降低至传统方案的10%以内。本文将深入解析TDengine的压缩算法原理与配置实践,帮助开发者构建高效、低成本的时序数据存储方案。

一、TDengine压缩架构概览

1.1 列式存储与压缩的天然契合

TDengine采用列式存储架构,同一列的数据类型相同、取值范围相近,这为高效压缩创造了理想条件。相比行式存储,列式存储的压缩率通常可提升3-5倍。

-- 查看表的压缩配置
DESCRIBE db.meters;

1.2 两级压缩机制

TDengine实现了独特的两级压缩架构:

压缩层级压缩类型算法特点适用场景
一级压缩数据类型专用差值、位编码、zigzag等利用时序数据特征
二级压缩通用算法LZ4、ZLIB、ZSTD、XZ进一步压缩数据体积

二、一级压缩:数据类型专用算法

一级压缩针对不同数据类型采用专门的编码算法,充分利用时序数据的特征规律。

2.1 时间戳压缩:差值编码(Delta Encoding)

时序数据的时间戳通常具有高度规律性,相邻数据点的时间间隔相对固定。差值编码只存储相邻时间戳的差值,而非完整时间戳。

-- 原始时间戳序列(毫秒)
-- 1699123200000, 1699123201000, 1699123202000, 1699123203000

-- 差值编码后
-- 1699123200000, 1000, 1000, 1000

压缩效果:64位时间戳经差值编码后,通常可用8-16位表示,压缩比可达4:1至8:1。

2.2 布尔值压缩:位编码(Bit Encoding)

布尔类型只有两个取值,传统存储需要1字节。TDengine采用位编码,8个布尔值仅需1字节。

-- 原始布尔序列
-- true, false, true, true, false, true, false, false

-- 位编码后(1字节)
-- 10110100 (二进制)

压缩效果:压缩比固定为8:1。

2.3 整数压缩:ZigZag编码

有符号整数采用ZigZag编码,将负数映射为正数,使小绝对值整数占用更少的编码空间。

原始值 -> ZigZag编码
0 -> 0
-1 -> 1
1 -> 2
-2 -> 3
2 -> 4

这种编码方式特别适合传感器数据,因为传感器读数通常在小范围内波动。

2.4 浮点数压缩:Delta-Delta编码

对于浮点数,TDengine采用delta-delta编码,存储相邻差值的差值。

-- 原始浮点序列
-- 25.3, 25.5, 25.8, 26.0, 26.2

-- 一级差值
-- 0.2, 0.3, 0.2, 0.2

-- Delta-Delta编码(二级差值)
-- 0.2, 0.1, -0.1, 0

压缩效果:对于变化平缓的传感器数据,delta-delta编码可将64位浮点数压缩至8-16位。

2.5 字符串压缩:字典压缩(Dictionary Encoding)

对于重复率高的字符串(如设备型号、状态标识),TDengine采用字典压缩。

-- 原始字符串列
-- "temperature", "humidity", "temperature", "pressure", "temperature"

-- 字典映射
-- 0: "temperature"
-- 1: "humidity"
-- 2: "pressure"

-- 编码后
-- 0, 1, 0, 2, 0

压缩效果:对于枚举类字符串,压缩比可达10:1以上。

三、二级压缩:通用压缩算法

一级压缩后的数据进入二级压缩阶段,TDengine支持多种通用压缩算法:

3.1 支持的压缩算法

算法压缩比压缩速度解压速度适用场景
LZ4中等极快极快实时性要求高的场景
ZLIB较高中等中等平衡压缩比与性能
ZSTD推荐默认选择
XZ极高中等归档存储场景

3.2 压缩算法配置

在创建数据库时指定压缩算法:

-- 创建数据库,指定压缩算法为ZSTD
CREATE DATABASE db COMPRESS 2;

-- 压缩级别说明
-- 0: 不压缩
-- 1: LZ4(默认)
-- 2: ZLIB
-- 3: ZSTD
-- 4: XZ

3.3 表级压缩配置

-- 创建表时指定压缩选项
CREATE TABLE meters (
    ts TIMESTAMP,
    current FLOAT,
    voltage INT,
    phase FLOAT
) COMPRESS("current", "zstd") COMPRESS("voltage", "lz4");

四、有损压缩:TSZ算法

对于允许一定精度损失的场景,TDengine提供TSZ(Time Series Compression)有损压缩算法。

4.1 TSZ算法原理

TSZ基于预测模型,利用时序数据的趋势特征进行压缩:

  1. 预测阶段:根据历史数据预测下一个值
  2. 残差编码:只存储预测值与实际值的差值
  3. 精度控制:通过最大误差阈值控制压缩质量
-- 启用TSZ有损压缩(创建数据库时)
CREATE DATABASE db PRECISION '1ms' COMPRESS 3;

-- 设置压缩精度损失阈值
ALTER DATABASE db KEEP 365d;

4.2 TSZ适用场景

  • 监控指标数据(允许微小误差)
  • 历史归档数据
  • 大规模传感器数据采集

压缩效果:TSZ算法可实现20:1至50:1的压缩比,同时保持99%以上的数据精度。

五、传输压缩:网络带宽优化

除了存储压缩,TDengine还支持传输层压缩,降低网络带宽消耗。

5.1 传输压缩配置

-- 服务端配置(taos.cfg)
compressMsgSize 1024

-- 含义:消息大小超过1024字节时启用压缩

5.2 RESTful API压缩

# 启用gzip压缩的RESTful请求
curl -H "Accept-Encoding: gzip" \
     -H "Content-Type: application/json" \
     http://localhost:6041/rest/sql/db \
     -d "SELECT * FROM meters LIMIT 100"

5.3 WebSocket压缩

// WebSocket连接启用压缩
const ws = new WebSocket('ws://localhost:6041/ws', {
    perMessageDeflate: true
});

六、压缩性能优化实践

6.1 压缩算法选择建议

数据特征推荐算法理由
高频实时写入LZ4压缩速度快,不影响写入性能
历史归档数据XZ最大化压缩比,节省存储成本
通用场景ZSTD压缩比与速度的最佳平衡
允许精度损失TSZ极致压缩比

6.2 监控压缩效果

-- 查看数据库占用空间
SELECT * FROM information_schema.ins_databases;

-- 查看超级表数据量
SELECT COUNT(*) FROM db.meters;

6.3 压缩率优化技巧

  1. 合理设置数据类型:使用最小的足够数据类型
   -- 推荐:使用TINYINT代替INT存储小范围整数
   CREATE TABLE sensors (status TINYINT);
  1. 利用标签去重:将不变属性放入标签而非列
   -- 推荐做法
   CREATE STABLE meters (ts TIMESTAMP, val FLOAT) 
   TAGS (device_id BINARY(20), location BINARY(50));
  1. 批量写入:减少压缩开销,提高压缩效率

七、总结

TDengine通过创新的两级压缩架构,将时序数据库的存储效率提升到了新的高度。一级压缩利用数据类型特征实现高效编码,二级压缩通过通用算法进一步压缩体积,配合可选的TSZ有损压缩,整体压缩率可达原始数据的10%以内。

在实际应用中,建议根据业务场景选择合适的压缩算法:实时性优先选择LZ4,存储成本敏感选择ZSTD或XZ,允许精度损失的场景可启用TSZ算法。通过合理的压缩配置,企业可在保证查询性能的同时,大幅降低时序数据的存储成本。

TDengine作为国产开源时序数据库的代表,其压缩技术已达到业界领先水平,为物联网、工业互联网等海量数据场景提供了经济高效的存储解决方案。