QingyaFan / blog

博客

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Prometheus数据存储压缩

QingyaFan opened this issue · comments

数据压缩意味着可以节省存储空间,也就意味着成本;同时,存储更多的数据,支撑更多的应用。

Gorilla压缩算法

社区主流的开源时序数据库都使用了 Gorilla 算法(Gorilla: A Fast, Scalable, In-Memory Time Series Database)来进行数据的压缩,Prometheus也是。

Gorilla 是 Facebook 的时序数据库,在论文里,为了提高查询效率,将数据压缩到了原来的 1/10,这样就可以把数据加载进内存,将查询 latency 降为原来的 1/73,提升了 14 倍的吞吐,这些提升的关键是数据压缩,主要手段是:

  • delta-of-delta timestamps
  • XOR'd floating point values

打开WAL

对于生产级数据存储方案,数据压缩是必要的,Prometheus可以通过开启 WAL 将磁盘占用减少到原来的大约 50%:

--storage.tsdb.wal-compression: Enables compression of the write-ahead log (WAL). Depending on your data, you can expect the WAL size to be halved with little extra cpu load. This flag was introduced in 2.11.0 and enabled by default in 2.20.0. Note that once enabled, downgrading Prometheus to a version below 2.11.0 will require deleting the WAL.

为什么开启WAL,就可以减少磁盘占用呢?

WAL 是 Write Ahead Log,顾名思义,就是在真正写入磁盘之前,会先落一条日志,这条日志基本上等同于命令,可以回放执行来进行数据恢复。

默认情况下,Prometheus会将每个样本都写入磁盘,并且在内存中维护一个倒排索引(Inverted Index)以加快查询速度。这种方式虽然能够提供快速的查询,但对磁盘空间的利用不是很高,因为它需要频繁地写入磁盘,每条数据都有一个写磁盘操作。开启WAL后,会先将样本写入WAL,然后攒一批,再异步地持久化到磁盘中。这种方式使得磁盘写入的频率大大降低,可以减少磁盘的随机写入,提高磁盘利用率,并且降低了由于频繁写入而造成的磁盘碎片 🧩。

WAL vs wlog

wal的实现在 tsdb/wal.go 中,wlog 实现在 wsdb/wlog/ 中

VictoriaMetrics的数据压缩

相对于 prom,vm的数据磁盘占用可以达到 prom的 1/7,参考:
https://valyala.medium.com/prometheus-vs-victoriametrics-benchmark-on-node-exporter-metrics-4ca29c75590f

社区主流的开源时序数据库都使用了 Gorilla 算法(Gorilla: A Fast, Scalable, In-Memory Time Series Database)显著减少磁盘空间占用,但因为需要大量的索引结构和字典,会导致内存占用较高,特别是处理大量时间序列数据时。但 vm 则改进了 Gorilla,使之有更好的数据压缩效果(参考https://faun.pub/victoriametrics-achieving-better-compression-for-time-series-data-than-gorilla-317bc1f95932):

  • 将float转换成 int,通过 * 10^X
  • 将counter转换成 gauge
  • 在编码后的数据基础上再使用一般的压缩算法

当然,做这些操作势必会涨 CPU,但vm的作者认为相对于节省的磁盘来说,cpu的涨幅不值一提。