壓縮篇: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 算法也存在必定的缺陷,由於是不定長的壓縮算法,因此致使解壓後必須從數據塊的首地址依次計算。

附錄

轉載請註明出處,歡迎關注個人公衆號:亞普的技術輪子

亞普的技術輪子
相關文章
相關標籤/搜索