TDengine 列级压缩配置指南:ENCODE / COMPRESS / LEVEL 详解与原理分析
2026/9/20 23:14:19 网站建设 项目流程

TDengine 列级压缩配置指南:ENCODE / COMPRESS / LEVEL 详解与原理分析

【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengine

TDengine 从 3.3.0.0 版本起提供了更高级的数据压缩特性,允许用户在创建表时为每一列单独配置是否压缩、采用哪种压缩算法以及压缩级别。本文以官方文档为核心,结合仓库源码与测试,系统讲解压缩的分级体系、各数据类型的默认算法、完整的 SQL 配置语法,以及压缩参数在底层源码中的校验与映射逻辑,帮助你在 IoT、IT 监控等场景下按数据特征精细调优存储开销与读写性能。

压缩术语:两级压缩与三级压缩档位

理解 TDengine 的列级压缩配置,首先需要厘清两个容易混淆的概念:压缩阶段(Compression Stages)与压缩级别(Compression Levels)。

压缩阶段(两级压缩)

  • 第一级压缩(编码 Encoding):对数据进行编码,本质上就是一种压缩。例如整数的simple8b编码、时间戳的delta-i差分编码、浮点数的delta-d/bss字节流拆分等,都属于第一级压缩。
  • 第二级压缩:在编码结果之上,再对数据块执行一次通用压缩算法(如lz4zlibzstdxztsz),进一步压缩存储空间。

从源码结构看,TDengine 的压缩实现位于 source/util/src/tcompression.c,其中tsCompressINTImptsCompressDoubleImptsCompressBoolImptsCompressTimestampImptsCompressStringImp等函数分别实现了各数据类型的第一级编码;而l2CompressImpl_lz4l2CompressImpl_zstdl2CompressImpl_zlibl2CompressImpl_xzl2CompressImpl_tszl2CompressImpl_disabled则实现了第二级压缩(对应源码中的l2前缀,即 level-2,第二级压缩)。

压缩级别(三级档位)

文档中的"压缩级别"特指第二级压缩算法(如 zstd)的内部档位。以 zstd 为例,其原生支持至少 8 个级别,不同级别在压缩率、压缩速度和解压速度上各有取舍。为避免用户选择困难,TDengine 将其简化为以下三档:

  • high:压缩率最高,压缩与解压速度相对最差;
  • low:压缩与解压速度最好,压缩率相对最低;
  • medium:在压缩率、压缩速度、解压速度之间取得平衡。

算法清单与各数据类型默认配置

可用算法

  • 第一级压缩(编码)算法:simple8bbit-packingdelta-idelta-ddisabledbss(byte-stream-split,字节流拆分)
  • 第二级压缩算法:lz4zlibzstdtszxzdisabled

其中tsz仅适用于FLOATDOUBLE类型。

各数据类型的算法与默认值

数据类型可用编码算法默认编码算法可用压缩算法默认压缩算法默认压缩级别
INT/UINTdisabled/simple8bsimple8blz4/zlib/zstd/xzlz4medium
TINYINT/UTINYINT/SMALLINT/USMALLINTdisabled/simple8bsimple8blz4/zlib/zstd/xzzlibmedium
BIGINT/UBIGINTdisabled/simple8b/delta-isimple8blz4/zlib/zstd/xzlz4medium
TIMESTAMPdisabled/delta-idelta-ilz4/zlib/zstd/xzlz4medium
FLOAT/DOUBLEdisabled/delta-d/bssbsslz4/zlib/zstd/xz/tszlz4medium
BINARY/NCHARdisableddisabledlz4/zlib/zstd/xzzstdmedium
BOOLdisabled/bit-packingbit-packinglz4/zlib/zstd/xzzstdmedium
DECIMALdisableddisabledlz4/zlib/zstd/xzzstdmedium

源码中的默认值印证

上述默认值可以在 source/common/src/tcol.c 中找到对应实现。例如getDefaultEncodegetDefaultCompress函数根据数据类型返回默认编码与默认压缩算法:整型默认simple8b,时间戳默认delta-iBINARY/NCHAR/DECIMAL默认zstdTINYINT/UTINYINT/SMALLINT/USMALLINT默认zlib,其余多数类型默认lz4getDefaultLevel则统一返回TSDB_COLVAL_LEVEL_MEDIUM,与文档中"默认压缩级别为 medium"一致。

编码与压缩算法的字符串常量定义在 include/common/tcol.h,例如TSDB_COLUMN_ENCODE_SIMPLE8B"simple8b"TSDB_COLUMN_ENCODE_BYTE_STREAM_SPLIT"bss"TSDB_COLUMN_COMPRESS_TSZ"tsz"TSDB_COLUMN_LEVEL_HIGH"high",选项字符串缓冲区长度为TSDB_CL_COMPRESS_OPTION_LEN(12 字节)。

SQL 语法:创建表时指定压缩配置

建表(或建超级表)时指定压缩

CREATE TABLE [db_name.]tb_name ( col_name col_type [ENCODE 'encode_type'] [COMPRESS 'compress_type'] [LEVEL 'level'] [, ...] );
  • tb_name:普通表或超级表的表名;
  • encode_type:第一级压缩(编码)算法,取值见上文算法清单;
  • compress_type:第二级压缩算法,取值见上文算法清单;
  • level:第二级压缩级别,默认medium,也支持缩写'h'/'l'/'m'

超级表(supertable)的列定义同样支持ENCODECOMPRESSLEVEL三个选项,具体语法可参考 创建超级表。

以下是一个完整的建表示例:

CREATE TABLE device_data ( ts TIMESTAMP ENCODE 'delta-i' COMPRESS 'lz4' LEVEL 'medium', device BINARY(64) COMPRESS 'zstd' LEVEL 'high', temp FLOAT ENCODE 'bss' COMPRESS 'tsz' LEVEL 'low', status BOOL ENCODE 'bit-packing' COMPRESS 'zstd', cnt INT ENCODE 'simple8b' COMPRESS 'zlib' );

注意:ENCODECOMPRESSLEVEL均为可选子句,不指定时使用该列类型的默认配置。

修改已有列的压缩方式

ALTER TABLE [db_name.]tb_name MODIFY COLUMN col_name [ENCODE 'encode_type'] [COMPRESS 'compress_type'] [LEVEL 'level'];
  • tb_name:表名,可以是超级表或普通表;
  • col_name:要修改压缩设置的列,仅能为普通列(不能是标签 tag)。

例如:

ALTER TABLE device_data MODIFY COLUMN temp COMPRESS 'lz4' LEVEL 'medium';

查看列的压缩方式

DESCRIBE [db_name.]tb_name;

DESCRIBE会展示列的基本信息,包括列类型和压缩设置。从源码看,DESCRIBE 的结果列数量由DESCRIBE_RESULT_COLS_COMPRESS决定,且结果中专门包含名为compress的列(见 source/libs/parser/src/parTranslater.c 附近的实现),该列的值由 source/common/src/tcol.c 中的columnEncodeStr/columnCompressStr/columnLevelStr将内部数值转换为可读的字符串形式。

源码视角:压缩参数如何被校验与存储

SQL 解析与参数校验

压缩选项在 SQL 解析阶段被识别。在 source/libs/parser/src/parAstCreater.c 中,解析器通过strcasecmp(optionType, "ENCODE")等比较识别ENCODE/COMPRESS选项,并将非法参数映射为相应的错误码:编码非法报TSDB_CODE_TSC_ENCODE_PARAM_ERROR,压缩算法非法报TSDB_CODE_TSC_COMPRESS_PARAM_ERROR,压缩级别非法报TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR

参数合法性检查实现在 source/common/src/tcol.c:

  • checkColumnEncode:将用户输入的编码字符串转为小写后,与supportedEncode列表比对;
  • checkColumnCompress:同理比对supportedCompress列表(共 6 项,见文件开头的supportedCompress[6]定义);
  • checkColumnLevel:长度 1 时仅接受'h'/'m'/'l',否则比对supportedLevel列表;
  • validColEncode/validColCompress/validColCompressLevel:进一步校验该算法是否适用于指定数据类型。

其中validColEncode中的注释清晰地总结了类型与编码的对应关系:

// |tinyint/smallint/int/bigint/utinyint/usmallinit/uint/ubiginint| simple8b | // | timestamp/bigint/ubigint | delta-i | // | bool | bit-packing | // | float/double | delta-d/byte-stream-split |

validColCompress中特别规定:tsz仅当列为FLOATDOUBLE时才合法,否则返回非法。

压缩选项的位域存储

校验通过后,编码、压缩算法、压缩级别被压缩进一个 32 位的整数:

  • setColEncode:编码值写入高 8 位(第 24-31 位);
  • setColCompress:压缩算法值写入第 8-15 位;
  • setColLevel:压缩级别写入低 8 位(第 0-7 位)。

若压缩算法为disabled,则压缩级别同时被置为TSDB_COLVAL_LEVEL_DISABLED。这一紧凑的位域设计使得每个列的压缩配置可以作为一个uint32_t随列元数据存储,具体可参考setColCompressByOptioncreateDefaultColCmprByType的实现。

压缩级别的底层映射

三档级别最终会映射为各算法内部的实际参数。在 source/util/src/tcompression.c 中可以看到一个映射表:

{"unknown", .lvl = {1, 2, 3}}, {"lz4", .lvl = {1, 2, 3}}, {"zlib", .lvl = {1, 6, 9}}, {"zstd", .lvl = {1, 11, 22}}, {"tsz", .lvl = {1, 2, 3}}, {"xz", .lvl = {1, 6, 9}},

tsGetCompressL2Level根据L2_LVL_LOW/L2_LVL_MEDIUM/L2_LVL_HIGH三档分别取出对应算法的实际级别。例如:

  • zstd三档映射为 1 / 11 / 22,即low用级别 1、medium用级别 11、high用级别 22;
  • zlibxz映射为 1 / 6 / 9;
  • lz4tszunknown映射为 1 / 2 / 3。

这也解释了为什么high档"压缩率最高但速度相对最差":映射到的 zstd 22 级等参数会在压缩时显著提升压缩比,但付出更多 CPU 开销。

压缩执行路径

在数据落盘时,先执行第一级编码,再执行第二级压缩。以浮点列为例,tsCompressDouble(见 source/util/src/tcompression.c)会根据列元数据中的编码算法选择tsEncodeDouble等编码函数完成第一级编码,随后依据配置的第二级算法(lz4/zstd/zlib/xz/tsz)调用l2CompressImpl_*系列函数完成第二级压缩。解压时反向执行l2DecompressImpl_*与解码函数。l2CompressImpl_lz4使用LZ4_compress_defaultl2CompressImpl_zstd使用ZSTD_compress(..., lvl)并将级别参数透传给底层算法。压缩与解压的完整往返逻辑可进一步参考仓库中的压缩测试用例 source/util/test/decompressTest.cpp。

兼容性说明

  • 完全兼容已有数据:升级到 3.3.0.0 后,历史数据仍可正常读取与查询,压缩配置的新特性不影响已有数据文件;
  • 不支持降级:升级到 3.3.0.0 之后无法回退到更低版本,规划升级时需注意。

实战建议

  • 时间戳列:默认delta-i+lz4已针对时序数据特征优化,通常无需修改;若对空间极度敏感,可尝试LEVEL 'high'提升压缩率。
  • 浮点数列(温度、电压等传感器值)bss编码对高位字节重复的浮点数据效果显著;若数据波动剧烈且希望极限压缩,可组合COMPRESS 'tsz'(tsz 为有损压缩,适用于对精度有容忍度的场景,需谨慎评估业务可接受误差)。
  • 字符串列:默认zstd压缩率优秀,长文本场景建议保持默认;BINARY/NCHAR不支持编码,只能配置第二级压缩。
  • 布尔列:默认bit-packing编码可将多个布尔值打包进更少的字节,适合大量开关类指标。
  • 中小整型TINYINT/SMALLINT等):默认zlib,若追求写入/查询速度可改为lz4

通过DESCRIBE可随时核对各列的最终压缩配置,便于在调优前后对比验证。

【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询