时序数据库作为物联网、工业互联网和金融交易等领域的核心基础设施,面临着海量数据存储的巨大挑战。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基于预测模型,利用时序数据的趋势特征进行压缩:
- 预测阶段:根据历史数据预测下一个值
- 残差编码:只存储预测值与实际值的差值
- 精度控制:通过最大误差阈值控制压缩质量
-- 启用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 压缩率优化技巧
- 合理设置数据类型:使用最小的足够数据类型
-- 推荐:使用TINYINT代替INT存储小范围整数
CREATE TABLE sensors (status TINYINT);
- 利用标签去重:将不变属性放入标签而非列
-- 推荐做法
CREATE STABLE meters (ts TIMESTAMP, val FLOAT)
TAGS (device_id BINARY(20), location BINARY(50));
- 批量写入:减少压缩开销,提高压缩效率
七、总结
TDengine通过创新的两级压缩架构,将时序数据库的存储效率提升到了新的高度。一级压缩利用数据类型特征实现高效编码,二级压缩通过通用算法进一步压缩体积,配合可选的TSZ有损压缩,整体压缩率可达原始数据的10%以内。
在实际应用中,建议根据业务场景选择合适的压缩算法:实时性优先选择LZ4,存储成本敏感选择ZSTD或XZ,允许精度损失的场景可启用TSZ算法。通过合理的压缩配置,企业可在保证查询性能的同时,大幅降低时序数据的存储成本。
TDengine作为国产开源时序数据库的代表,其压缩技术已达到业界领先水平,为物联网、工业互联网等海量数据场景提供了经济高效的存储解决方案。
























