深入淺出時序資料庫之壓縮篇

2021-09-23 08:17:23 字數 3031 閱讀 2960

壓縮對於時序資料庫是至關重要的。因為時序資料庫面對的物聯網場景每天都會產生上億條資料。眾所周知,在大資料時代的今天資料的重要性是不言而喻的,資料就是公司的未來。但如果無法對這些時序資料進行很好的管理和壓縮,那將給客戶帶來非常高的成本壓力。

如前文提到的,工業物聯網環境監控方向的客戶,一年產生 1p 的資料,如果每台伺服器 10t 的硬碟,那麼總共需要 100 多台。按照每台伺服器 3 萬來算,一年就需要 300 萬的支出,這還不包括維護人員的成本。

壓縮是個非常大的話題,本文希望能夠先從大的巨集觀角度給出乙個輪廓,講述壓縮的本質,壓縮的可計算性問題。再從時序資料壓縮這乙個垂直領域,給出無失真壓縮和有失真壓縮各乙個例子進行說明,希望能夠拋磚引玉。

壓縮的故事

先來講個有關壓縮的故事,外星人拜訪地球,看中了大英百科全書,想要把這套書帶回去。但這套書太大,飛船放不下。於是外星人根據飛船的長度,在飛船上畫了乙個點。這樣外星人心滿意足的返回了自己的星球,因為這個點就儲存了整個大英百科全書。

這個並不是很嚴謹的故事,卻道出了壓縮的本質:用計算時間換取儲存空間。外星人在飛船上畫的點非常有技術含量,可以說是黑科技,代表乙個位數非常長的不迴圈小數。而這串數字正代表了整個大英百科全書的內容。

壓縮的兩個問題

再來回答兩個巨集觀的問題,幫助我們認識在壓縮這件事上哪些是我們能做的,哪些是不能做的。

第乙個問題:是否存在乙個通用的壓縮演算法(universal compression),也就是說某個壓縮演算法能夠壓縮任意的資料。答案是否定的,並不存在這樣的通用壓縮演算法。

用反證法可以做個快速的證明。假設存在通用的壓縮演算法,也就是說有個壓縮演算法,對於長度為 n 的字串,總能壓縮到長度小於 n 的字串。總共有 2^n 個長度為 n 的不同字串;但卻只有 2^n-1 個長度小於 n 的字串。那麼必定存在兩個長度為 n 的字串 a,b,經過壓縮得到同乙個字串。這樣解壓縮演算法沒有辦法正確的解壓。所以假設錯誤,並不存在通用的壓縮演算法。

這兩個問題的答案,告訴我們三件事情,

壓縮演算法的選擇需要具體情況具體分析,不可壓縮的字串總是存在。

不要妄圖獲得最好的壓縮演算法,它是不可計算的。因為總有你想不到的壓縮演算法存在。舉個例子,[一百萬個 0 的字串,以「foo」作為 key,經過 aes 加密演算法的 cbc 模式得到的字串]。這串字串看起來完全是隨機的,不可壓縮的。但我卻用 43 個中文(中括號之間的內容)就表示了出來。

壓縮是件很難很有技術含量的事情,需要不斷的挖掘,才能將他做到更好。

時序資料壓縮

如果要得到更好的壓縮率,我們需要採取更加適合時序資料的壓縮演算法。時序資料的壓縮可以分為無失真壓縮和有失真壓縮。

無失真壓縮

無失真壓縮是說被壓縮的資料和解壓後的資料完全一樣,不存在精度的損失。對資料的壓縮說到底是對資料規律性的總結。時序資料的規律可以總結為兩點: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 非常的火,讓人很好奇它是不是可以給資料壓縮帶來新的方案。

MFC深入淺出之基礎篇

引言 mfc是microsoft foundation classes的縮寫,它是建立在windows api之上的c 類庫,目的是使windows程式設計過程更有效率,更符合物件導向的設計思想。一 windows程式設計 windows程式的執行是依靠外部發生的事件來驅動的,即程式不斷等待任何可能...

深入淺出資料庫結構 一

一 資料庫結構 資料結構 陣列 插入快 知道下標 查詢慢,刪除慢,大小固定 有序陣列 比無序陣列查詢快 刪除和插入慢,大小固定 棧提供先進後出的訪問方式 訪問其他項很慢 佇列提供先進先出的訪問方式 訪問其他項很慢 鍊錶插入快,刪除快 查詢慢二叉樹 查詢插入刪除都快 刪除演算法複雜 紅黑樹查詢 插入 ...

資料庫索引的深入淺出

了不了解索引的原理,其實根據資料的大小有很大的關係,其實很多事情你會發現,資料量1萬以下不是個事情,但是如果資料量達到了1000萬之類的量級,那麼優化,查詢可能就是會成為瓶頸。所以說,很多系統都是資料量小都不是問題,資料量一大,基本上就全是問題了。說白了,索引問題就是乙個查詢問題。資料庫索引,是資料...