压缩篇:delta-of-delta编码

前言

本文主要讨论时序数据库中常见的一种时间戳或者数值压缩方法:delta-of-delta 算法,能够极大地下降数据存储的成本和提升数据写入、查询的性能。git

delta-of-delta 压缩时间戳是 Facebook Gorilla 论文中所提到的,论文地址:www.vldb.org/pvldb/vol8/… Prometheus TSDB 项目也是借鉴了 Facebook Gorilla 论文中的思路,能够实现很高的时序数据压缩率。github

delta 时间戳压缩

时间戳通常采用 long 类型进行存储,须要占用 8byte 存储空间。最直接的优化就是存储时间戳的差值,这里须要起始时间戳和 delta 的最大范围阈值。有两种经常使用的实现思路:算法

  • 存储相邻两个时间戳差值 Delta(n) = T(n) - T(n-1)
Unix时间戳 Delta
1571889600000 0
1571889600010 10
1571889600025 15
1571889600030 5
1571889600040 10
  • 存储与起始时间戳的差值 Delta(n) = T(n) - T(0)
Unix时间戳 Delta
1571889600000 0
1571889600010 10
1571889600025 25
1571889600030 30
1571889600040 40

假设起始时间戳为 1571889600000,delta 的最大范围阈值为 3600s,每一个 delta 的数值须要 13bit 能够存储。所以以上时间戳数据共占用空间为 64 + 13 * 4 = 116bit。数据库

思路 2 的优点是不须要对块内数据依次遍历,可是相比思路 1 可能须要更为频繁地更换起始时间,根据实际需求选择合适的压缩方案。性能

delta-of-delta 时间戳压缩

Facebook Gorilla 有详细阐述 delta-of-delta 编码的计算方式,如下为论文的摘录。优化

image

针对不一样时间跨度的数据,Facebook Gorilla 给出了一种较为通用的处理方案。编码

D 标识位 占用总bits
0 0 1
[-63,64] 10 2 + 7 = 9
[-255,256] 110 3 + 9 = 12
[-2047,2048] 1110 4 + 12 = 16
> 2048 1111 4 + 32 = 36

依然经过一组时间戳数据来直观感觉下 delta-of-delta 编码的压缩效果:cdn

Unix时间戳 delta delta-of-delta 压缩后总bits
1571889600000 0 0 --
1571889600010 10 10 9
1571889600010 0 -10 9
1571889600011 1 1 9
1571889600012 1 0 1
1571889600013 1 0 1
1571889600015 2 1 9
1571889600017 2 0 1

依然假设起始时间戳为 1571889600000,delta 的最大范围阈值为 3600s,占用存储空间对好比下:blog

  • delta 算法: 64 + 13 * 7 = 155bit 。
  • delta-of-delta 算法: 64 + 9 * 4 + 1 * 3 = 103bit 。

能够看出 delta-of-delta 算法相比 delta 算法进一步得到了更高的压缩率。在实际应用场景中,海量时序数据的时间戳都是密集且连续的,绝大部分都知足 delta-of-delta=0 的条件,这样能够大幅度下降时间戳的存储空间。get

总结

  • delta-of-delta 算法经常使用于监控数据中时间戳的压缩,能够大幅度下降存储成本和提升写入、查询性能。
  • 针对跨度较大的数据,系统须要有必定的容错能力。
  • delta-of-delta 算法也存在必定的缺陷,由于是不定长的压缩算法,因此致使解压后必须从数据块的首地址依次计算。

附录

转载请注明出处,欢迎关注个人公众号:亚普的技术轮子

亚普的技术轮子
相关文章
相关标签/搜索