无损压缩
无损压缩是说被压缩的数据和解压后的数据完全一样,不存在精度的损失。对数据的压缩说到底是对数据规律性的总结。时序数据的规律可以总结为两点:1、timestamp 稳定递增、2、数值有规律性,变化稳定。下面来举个例子。
上图是一组时序数据,如果我们一行一行的看感觉压缩有点困难,但如果我们一列一列的看,压缩方案就呼之欲出了。
先看 timestamp 那一列是等差递增数列,可以用 [1467627245000,1000,4] 来表示。1467627245000 代表了第一个时间,1000 代表后一个时间比前一个时间的大 1000,4 代表了这样的规律出现了 4 次。如果一共有 100 个这样规律的 timestamp,那就意味着,我们用 3 个 Long 型就可以表示出来。timestamp 压缩率高达 33。
再进一步观察看 value 那一列,如果取差值,可以得到(6,-5,2,-5),全部都加 5 得到(11,0,7,0),这些数值都可以用 4bit 来表示。也就是用 [23,5,4,0xb0700000] 来表示(23,22,24,25,24)。其中的 4 代表后续一共有 4 个数。如果这样的规律一直维持到 100 个 Int 的 value,就可以用 16 个 Int 来代表,压缩率高达 6.3。
具体的情景会复杂很多,在此只是简单举个例子。InfluxDB 无损压缩算法在其页面上有完整的阐述(注 3),可以配合开源源码进行更加深入的理解。针对于浮点数类型,Facebook 在 Gorilla 论文中(注 4)提到的非常高效的无损压缩算法,已经有很多文章进行分析。InfluxDB 对于浮点型也采用这个算法。
有损压缩
有损压缩的意思是说解压后的数据和被压缩的数据在精度上有损失,主要针对于浮点数。通常都会设置一个压缩精度,控制精度损失。时序数据的有损压缩的思路是拟合。也就是用一条线尽可能的匹配到这些点,可以是直线,也可以是曲线。
最有名的时序数据有损压缩是 SOIsoft 公司的 SDA 算法,中文称为旋转门压缩算法。
在上图中,红色的点是上一个记录的点,空心的点是被丢掉的点,绿色的点是当前的点,黑色的点是当前要记录的点。
可以看到图左边,当前点和上一个记录点以及压缩精度的偏差值形成的矩形可以包含中间的点,所以这些点都是可以丢掉的。
再看图右边,当前点和上一个记录点形成的矩形无法包含中间的点,所以把上一个点记录下来。如此进行下去,可以看到,大部分的数据点都会被丢掉。查询的时候需要根据记录的点把丢掉的点在插值找回来。
有损压缩除了可以大幅减少存储成本。如果结合设备端的能力,甚至可以减少数据的写入,降低网络带宽。
总结
虽然判断压缩算法最优是不可计算的,但是设计好的压缩算法仍然是可计算的问题。可以看到,前面提到的时序数据的无损压缩有损压缩算法都会基于时序数据的特征采取方案,达到更好的压缩率。现在 deep learning 非常的火,让人很好奇它是不是可以给数据压缩带来新的方案。