用LLM定制压缩算法

使用 LLM 帮助为我们的温湿度时间序列数据制作了定制压缩算法,将其压缩了约 x53.6。

用LLM定制压缩算法

我们的移动客户端不断接收来自婴儿监视设备的温度和湿度读数,我们希望存储这些数据。设备每 5 分钟发送一次读数,我们需要将其以 7 天的分辨率存储,准备好按设备提供服务。

1、问题

我们正在为移动客户端服务 temperaturehumidity 传感器数据。设备的插入速率很高,每秒数千次读数,但查询频率却很低。

当前的数据格式如下:

timestamp : `u32` 32位无符号整数,自纪元以来的秒数
device_id : `i8`  8位无符号整数,设备标识符
value     : `i8`  8位无符号整数,温度或湿度读数

每个读数大约 5 字节(时间戳 4 字节,设备 ID 1 字节,数值 1 字节)。考虑到这种格式,存储 100 万个设备读数(7 天数据)大约需要 400MB。以目前的规模,这将是巨大的(~400GB for a 7-day retention)。

要求:

  • Appendable in O(1):我们需要能够追加新的读数,而无需每次都解码整个序列。移动客户端会按设备 ID 和日期查询数据,并可能请求特定时间范围。
  • 保留间隔:客户端将原始读数显示为随时间变化的图表,因此间隔必须被保留。我们使用 timestamp(自纪元以来的时间)来表示这一点。
  • 处理数据缺口:由于网络问题或设备离线,某些读数可能会丢失。当发生这种情况时,我们不应跳过时间戳,而应保留间隔。
  • 存储效率:我们希望优化存储,而不浪费空间来表示相同的值。

2、解决方案

2.1 最简单的方案:只存储时间戳和数值

我们可以只保留 timestampdevice_idvalue,而省略 delta。这将把读数减少到大约 3 字节。

优点

  • 最简单的实现
  • 最小的存储大小
  • 不需要任何额外解码逻辑

缺点

  • 客户端无法轻松可视化变化
  • 无法计算插入率
  • 没有内置的间隙检测

2.2 更好的方案:RLE 运行长度编码

对于重复值,我们可以只存储第一个实例和计数。

timestamp : `u32`
device_id : `i8`
value     : `i8`
count     : `u8` 8位无符号整数,读数重复计数

优点

  • 仍然保留时间戳
  • 存储开销仍然很小(仅额外的 1 字节用于计数)
  • 客户端可以轻松检测缺失的读数

缺点

  • 仍然无法轻易可视化原始时间序列
  • 需要客户端实现解包逻辑

2.3 最佳方案:Delta + Zstd 编码

对于重复值,我们存储第一个值和与下一个值之间的差值(delta),并使用 zstd 压缩差值。

timestamp : `u32`
device_id : `i8`
delta     : `i8` 8位有符号整数,与前一读数的差值
value     : `i8` 被跳过(delta = 0 时)

优点

  • 极小的差值(通常 ±10,1 字节)
  • 客户端仍然可以可视化时间戳
  • 空值可以表示"无变化"
  • 比原始 5 bytes 节省约 70-80% 空间

缺点

  • 需要客户端计算实际时间戳(base_ts + sum(deltas))
  • 无法轻松检测间隙(如果值每 5 分钟保持不变,delta 将为 0)
  • 需要特殊逻辑来正确解码(必须按顺序处理读数)

3、当前实现

3.1 PCO L4 压缩 (25.8x 压缩比)

该实现使用 PCO (预测编码优化) 算法,这是一种专为物联网时间序列设计的编码方案。

示例压缩结果

方法 平均大小 压缩比 可追加?
未压缩 3270B 1.0x
PCO L4 ~117B 27.9x
TSZ (Gorilla) ~140B 23.5x
RLE Delta ~146B 22.5x

主要特征

  • 在物联网工作负载下实现了良好的压缩比
  • 保持完整的时间戳
  • 支持缺失数据的间隙处理
  • 适用于我们的数据特征(重复值)

缺点

  • 比简单的基于计数的解决方案慢
  • 在没有硬件加速的情况下可能不够高效

3.2 运行长度编码 (变长)

这是最简单的改进,使用 1-3 字节运行长度来表示读数。

压缩结果:~61B,~18.6x 压缩比。

优点

  • 比 PCO L4 更容易实现
  • 可以处理不同的数据大小
  • 无需复杂的位累加器

缺点

  • 仍然无法直接可视化时间序列
  • 客户端需要实现更多解码逻辑

3.3 变量长度编码 + 自适应运行长度

我们动态决定每个读数的运行长度(1、2 或 3 字节),根据数据模式。

改进

  • 最高的压缩效率
  • 适应不同数据模式
  • 可以处理不同的设备数量

4、性能基准

在 7 天的数据集(10,000 个设备读数)上进行测试:

方法 平均大小 压缩比
原始数据 3270B 1.0x
PCO L4 ~117B 27.9x
变长 ~61B 18.6x

最佳方法:PCO L4

在我们的测试中,PCO L4 被证明是最适合的,因为它提供了最好的压缩比,同时保持我们要求的所有功能。

5、我们可以做更好吗?

是的,有几个方向可以探索:

增量更新:如果数据以小批或增量形式接收,而不是一次性加载 7 天,我们可以优化内存使用。

边缘计算:如果我们发送原始读数到边缘设备并让它进行初步压缩,然后再发送到服务器,可以节省带宽和计算资源。

采样策略:如果我们不需要每个读数,可以使用更高的采样率(例如,每分钟而不是每 5 分钟),同时仍然保持足够的数据来进行有用的分析。

混合编码:对于重复数据使用 Delta + Zstd,对于唯一序列使用运行长度编码。

下一步行动:

  1. 评估 增量更新:确定我们是否可以以更小的批接收数据。
  2. 原型边缘压缩:创建一个服务端来接收原始读数并进行初步压缩,然后再发送到主数据库。
  3. 测试混合方法:实现 Delta + Zstd 编码,并测量其实际压缩比。
  4. 客户端协调:更新移动客户端以支持解码方法,包括间隙检测和正确的数据可视化。

原文链接: Hand-Crafting Domain-Specific Compression with an LLM

汇智网翻译整理,转载请标明出处