華為雲資料庫GaussDB(for Influx)揭祕第二期:解密GaussDB(for Influx)的資料壓縮

語言: CN / TW / HK

根據IDC的一份白皮書預測,到2025年全球資料總量將達到175ZB,其中物聯網裝置將生成90ZB資料,佔比50%以上。以往物聯網資料基本上都是先儲存起來再處理,如今這一處理模式開始向“實時處理”模式轉型。即便如此,資料的總量依然巨大,為降低資料儲存成本,迫切地要求減少資料儲存空間,這對資料壓縮技術提出了更高的要求。物聯網裝置產生的資料是典型的時序資料,而時序資料庫是儲存時序資料的專業資料庫系統,因此資料壓縮對時序資料庫來說是一項必不可少的能力。

什麼是資料壓縮?

眾所周知,資料在計算機內部是以二進位制方式表示和儲存,因此,資料壓縮,通俗地講,就是以最少的位元數表示資料物件。資料壓縮的本質是用計算時間換取儲存空間,不同資料型別對應不同的資料壓縮演算法,不存在某個壓縮演算法能夠壓縮任意資料。資料壓縮說到底是對資料趨勢性、規律性的總結,這個資料規律性可分為基於內容(比如影片的幀與幀之間,影象的畫素與畫素之間的相似)、基於表示(比如變換編碼,熵編碼)和基於碼流(比如差量壓縮,深度壓縮)等多種級別。

舉一個數據壓縮的簡單例子:給定一個字串"this is a example",正常情況下,每個字元佔用8個位元位,該字串含有17個字元(包含空格),每一個字元出現的頻率分別是a(2),e(2),h(1),i(2),m(1),p(1), t(1),s(2),x(1),l(1),空格(3). 現在我們按照字母出現的頻率進行編碼,用111表示' '(空格),001表示'a',110表示'e',011表示'i',000表示's',0101表示'h',1011表示'm',1000表示'p',0100表示't',1010表示'x',1001表示'l'。最後"this is a example"被編碼成 010001010110001110110001110011101010001101110001001110,共54個位元。相比未壓縮前的136位元,儲存空間縮小了2.5倍。

時序資料是如何被壓縮的?

資料通過編碼、重組或以其他方式修改資料以減少其大小來實現壓縮的目的。前面例子中提到的方法叫Huffman編碼,它是發明最早的一種資料壓縮演算法,它在文字壓縮方面具有很優秀的表現。目前,資料壓縮領域發展迅速,新的技術和方法不斷湧現,層出不窮。一般我們將資料壓縮技術分為有失真壓縮和無失真壓縮兩大類。有失真壓縮,顧名思義,資料壓縮導致資料原本攜帶的資訊減少,有資訊丟失,且丟失的資訊無法恢復。無失真壓縮則相反,資料壓縮時沒有資訊丟失。在時序資料庫中,幾乎都支援無失真壓縮,只有極少數支援有失真壓縮。時序資料庫中常見的資料編碼和壓縮演算法有如下幾種:

遊程編碼(英語:run-length encoding,縮寫RLE)

一種與資料性質無關的無損資料壓縮技術,基於“使用變動長度的碼來取代連續重複出現的原始資料”來實現壓縮。舉例來說,一組字串“AAAABBBCCDEEEE” ,由4個A、3個B、2個C、1個D、4個E組成,經過RLE可將字串壓縮為4A3B2C1D4E。其優點是簡單、速度快,能將連續重複性高的資料壓縮成小單位。缺點也是明顯的,重複性低的資料壓縮效果不好。

XOR

該演算法是結合遵循IEEE754標準的浮點數儲存格式的資料特徵設計的特定演算法,第一個值不壓縮, 後面的值是跟第一個值計算XOR(異或)的結果,如果結果相同,僅儲存一個0,如果結果不同,儲存XOR後的結果。該演算法受資料波動影響,越劇烈壓縮效果越差。

Delta

差分編碼又稱增量編碼,編碼時,第一個資料不變,其他資料轉換為與上一個資料的delta。其原理與XOR類似,都是計算相鄰兩個資料的差異。該演算法應用廣泛,如需要檢視檔案的歷史更改記錄(版本控制、Git等)。在時序資料庫中,很少單獨使用,一般搭配RLE,Simple8b或者Zig-zag一起使用,壓縮效果更好。

Delta-of-Delta

又名二階差分編碼,是在Delta編碼的基礎上再一次使用Delta編碼,比較適合編碼單調遞增或者遞減的序列資料。例如 2,4,4,6,8 , Delta編碼後為2,2,0,2,2 ,再Delta編碼後為2,0,-2,0,0。通常也會搭配RLE,Simple8b或者Zig-zag一起使用。

Zig-zag

Zig-zag的出現是為了解決varint演算法對負數編碼效率低的問題,它的原理非常簡單,是將標誌位後移至末尾,並去掉編碼中多餘的0,從而達到壓縮的效果。對於比較小的數值壓縮效率很高,但是對於大的資料效率不但沒有提升可能還會有所下降。因此,Zig-zag通常和Delta編碼搭配,Delta可以很好的將大數值資料變為較小的數值。

Snappy

Snappy壓縮演算法借鑑了LZ77演算法的思路,由於LZ77演算法中模式匹配過程有較高的時間複雜度,Google對其做了許多優化,並於2011年對外開源。其原理是假設我們有一個序列S=[9,1,2,3,4,5,1,2,3,4],匹配發現子序列S~2,5~=[1,2,3,4]與S~7,10~=[1,2,3,4]是相同的,於是將該序列編碼為S=[9,1,2,3,4,5,6,(2,4)],2表示開始位置,4表示位數。Snappy的優點是速度快,壓縮率合理,在眾多開源專案中使用,比如Cassandra,Hadoop,MongoDB,RocksDB,Spark,InfluxDB等。

LZ4

LZ4資料壓縮演算法,它屬於面向位元組的LZ77壓縮方案家族,壓縮比並不高,它的特點是解碼速度極快。據官方測試基準 lzbench 的測試結果,預設配置下,解壓速度高達4970MB/s.。

Simple8b

Simple8b是64位演算法,實現將多個整形資料(在0和1<<60 -1之間)壓縮到一個64位的儲存結構中。其中前4位表示選擇器,後面60位用於儲存資料。優點是簡單高效,定長編碼保證瞭解壓效率。但對於大整數或者浮動較大的值,壓縮率較低,適用於範圍較小的無符號整數。

LZO

LZO是塊壓縮演算法,同樣屬於LZ77壓縮方案家族,該演算法的目標是快速壓縮和解壓縮,並非壓縮比。相比之下,LZ4的解壓速度更快。由於塊中存放的資料型別可能多種多樣,整體的壓縮效果遠沒有針對某一種資料型別進行壓縮的演算法好。

DEFLATE

DEFLATE是同時使用了LZ77演算法與哈夫曼編碼(Huffman Coding)的一個經典無損資料壓縮演算法。實際上deflate只是一種壓縮資料流的演算法。該演算法是zip檔案壓縮的預設演算法,在gzip,zlib等演算法中都有封裝。

Zstandard

Zstandard(Zstd)的設計目的是提供一個類似於DEFLATE演算法的壓縮比,但更快,特別是解壓縮。它的壓縮級別從負5級(最快)到22級(壓縮速度最慢,但是壓縮比最高)可以調節。在文字日誌壓縮場景中,壓縮效能與LZ4、Snappy相當甚至更好。Linux核心,HTTP協議,Hadoop,HBase等都已經加入對Zstd的支援,可以預見,Zstd將是未來幾年裡被廣泛關注的壓縮演算法。

Bit-packing

Bit-packing(位壓縮)壓縮演算法基於不是所有的整型都需要32位或者64位來儲存這一前提,從我們要壓縮的資料中刪除不必要的位。比如一個32位的整型資料,其值的範圍在【0,100】之間,則可以用7位就可以表示。

下表列舉了一些常見的開源時序資料庫和對應採用的資料壓縮演算法。

GaussDB(for Influx)的資料壓縮

時序資料的業務特徵決定了時序資料適合做壓縮,時序資料的資料特徵決定了時序資料可以被很好的壓縮。資料壓縮演算法的壓縮率和壓縮速度是一對矛盾,壓縮率高,壓縮速度就會慢,反之亦然,壓縮演算法需要根據業務情況在二者之間找到合適的平衡點。資料壓縮率與資料的儲存方式密切相關,實驗表明,行存的壓縮率相比列存的壓縮率差。為了達到更好的壓縮率,華為雲GaussDB(for Influx)時序資料庫採用列式資料儲存,相同資料型別的資料被存放在一起。在壓縮演算法層面,自研自適應壓縮演算法,針對不同資料型別和資料分佈自動適配合適的資料壓縮演算法;在演算法設計目標層面,資料的壓縮率、壓縮速度、解壓速度需要滿足每天萬億點寫入和海量資料下絕大部分運維監控與IoT場景典型業務的併發查詢效能要求。

時序資料的業務特徵

不變性:時序資料在寫入後,一般不會被修改。這個特徵非常適用於壓縮,不因修改某個資料對整個資料塊進行修改。

時效性:時間越近的資料被訪問的概率大,時間越是久遠,資料被訪問的概率越低。因此,對於時序的熱資料,可以採用壓縮和解壓速度比較好,壓縮率合理的壓縮演算法,而對於冷資料,非常適合使用更高壓縮比的演算法。

資料量龐大:時序資料的採集型別豐富, 隨著採集硬體的普及和採集頻率增加,使得資料量出現暴增,比如自動駕駛中每輛車每天就會採集將近 8TB的資料,頻寬、實時寫入、快速查詢、儲存、耗電以及維護成本都是挑戰。

資料生命週期:使用者可能對某些資料來源或者時間段的關注遠遠超過其他,因此在海量資料中偏向某些特殊時間段或某些資料來源的資料查詢。

時序資料的資料特徵

Timestamp:穩定遞增。某些時序資料是固定頻率取樣,例如城市空氣質量檢測儀每分鐘取樣一次pm2.5含量。還有部分時序資料是按照行為變化取樣的,比如股市裡的股價、交易資料、使用者使用行為。

Filed的時間屬性:同一資料來源產生的時序資料都因有時間屬性而有了先後順序性和時間間隔屬性。

Filed的取值特性:不同資料來源的不同指標值往往歸屬某個區間範圍,比如方向、速度、電壓、溫度等。

Filed的連續性:現實世界的事物是連續變化的,除非突發事件,或者接收資料的感測器裝置故障,否則同一資料來源的資料相鄰時間段內產生的資料比較接近,比如伺服器記憶體指標值的採集。

Filed的週期性:監控資料往往具有周期性或者規律性。

Filed的異常性:裝置故障或突發事件引起的異常性。例如某個新聞事件引起網站流量的激增。

GaussDB(for Influx)自適應壓縮演算法

“大道至簡”不僅是生活哲學,也是GaussDB(for Influx)自適應資料壓縮演算法的設計理念,化繁為簡,合適的才是最好的。

每一種壓縮方法都有其適合的資料型別和場景,比如Simple8b適合壓縮整型資料,但是不適合大整數或者浮動較大的值,如果固定一種壓縮演算法對應一種資料型別,遇到不適合的場景,資料壓縮演算法便會失效。

GaussDB(for Influx)自適應壓縮演算法是一套框架,為每一種資料型別註冊有若干具體資料壓縮演算法,比如Int(整型)有Simple8b、Delta、Delta-Of-Delta、Zigzag、ZSTD等。與傳統的資料壓縮演算法相比,本質區別在於一種資料型別並非固定一種資料壓縮演算法,而是根據資料型別和資料分佈選擇最合適的資料壓縮演算法,比如當檢測到大整型資料時,則放棄直接使用Simple8b,先使用Delta或者Delta-Of-Delta編碼後,再使用Simple8b亦或者Zigzag演算法。再比如Float(浮點)型資料,在大多時序資料庫中直接採用XOR演算法,但其實在實際的應用中,一些Float型別的資料可以轉為整型來處理效果更好。

GaussDB(for Influx)自適應壓縮演算法的優勢是擴充套件方便、靈活選擇,能充分發揮每個資料壓縮演算法的最優效能。已經整合的演算法有:RLE、Simple8b、Delta、Delta-Of-Delta、Zigzag、XOR、Zstd、Snappy、Bit-packing、LZ4等,未來還會繼續加入更多高效壓縮演算法。目前還不支援有失真壓縮,後續根據需要還會加入有失真壓縮演算法。

GaussDB(for Influx)與InfluxDB的壓縮率結果對比和資料集說明如下表所示:

從對比圖可以看出,自適應壓縮演算法相對於開源演算法在壓縮率方面有顯著提升,同時資料壓縮速度並未受損。

總結

如今我們正處在雲端計算、5G和物聯網的快速發展期,時序資料被越來越重要的同時,隨著資料量的暴增,企業的儲存成本也隨之提高,資料壓縮勢在必行。慶幸的是,時序業務的特點決定了時序資料非常適合被壓縮儲存,時序資料的特徵決定了時序資料可以被高效壓縮。時序資料庫作為時序資料儲存的基礎系統,資料壓縮能力顯得尤為重要。華為雲時序資料庫GaussDB(for Influx)通過對典型場景深入分析後,提出了一個更高效的時序資料壓縮演算法-自適應資料壓縮演算法,在風力發電物聯網場景下,250萬時間線和150億指標資料,整體資料壓縮比達到6.8,是開源InfluxDB的1.3倍,OpenTSDB的2.8倍,其他時序資料庫的2-3倍。在運維監控場景下,華為雲某服務儲存空間從每天1035GB降低到82GB,縮減了12.6倍。

本文作者:華為雲資料庫創新Lab & 華為雲時空資料庫團隊

歡迎加入我們!

雲資料庫創新Lab(成都、北京)簡歷投遞郵箱:[email protected]

華為雲時空資料庫團隊(西安、深圳)簡歷投遞郵箱:[email protected]

「其他文章」