摘要:物聯網裝置産生的資料是典型的時序資料,而時序資料庫是存儲時序資料的專業資料庫系統,是以資料壓縮對時序資料庫來說是一項必不可少的能力。
本文分享自華為雲社群《華為雲資料庫GaussDB(for Influx)揭秘第二期:解密GaussDB(for Influx)的資料壓縮》,作者: 高斯Influx官方部落格。
根據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編碼,它是發明最早的一種資料壓縮算法,它在文本壓縮方面具有很優秀的表現。目前,資料壓縮領域發展迅速,新的技術和方法不斷湧現,層出不窮。一般我們将資料壓縮技術分為有損壓縮和無損壓縮兩大類。有損壓縮,顧名思義,資料壓縮導緻資料原本攜帶的資訊減少,有資訊丢失,且丢失的資訊無法恢複。無損壓縮則相反,資料壓縮時沒有資訊丢失。在時序資料庫中,幾乎都支援無損壓縮,隻有極少數支援有損壓縮。時序資料庫中常見的資料編碼和壓縮算法有如下幾種:
一種與資料性質無關的無損資料壓縮技術,基于“使用變動長度的碼來取代連續重複出現的原始資料”來實作壓縮。舉例來說,一組字元串“AAAABBBCCDEEEE” ,由4個A、3個B、2個C、1個D、4個E組成,經過RLE可将字元串壓縮為4A3B2C1D4E。其優點是簡單、速度快,能将連續重複性高的資料壓縮成小機關。缺點也是明顯的,重複性低的資料壓縮效果不好。
該算法是結合遵循IEEE754标準的浮點數存儲格式的資料特征設計的特定算法,第一個值不壓縮, 後面的值是跟第一個值計算XOR(異或)的結果,如果結果相同,僅存儲一個0,如果結果不同,存儲XOR後的結果。該算法受資料波動影響,越劇烈壓縮效果越差。
差分編碼又稱增量編碼,編碼時,第一個資料不變,其他資料轉換為與上一個資料的delta。其原理與XOR類似,都是計算相鄰兩個資料的差異。該算法應用廣泛,如需要檢視檔案的曆史更改記錄(版本控制、Git等)。在時序資料庫中,很少單獨使用,一般搭配RLE,Simple8b或者Zig-zag一起使用,壓縮效果更好。
又名二階差分編碼,是在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的出現是為了解決varint算法對負數編碼效率低的問題,它的原理非常簡單,是将标志位後移至末尾,并去掉編碼中多餘的0,進而達到壓縮的效果。對于比較小的數值壓縮效率很高,但是對于大的資料效率不但沒有提升可能還會有所下降。是以,Zig-zag通常和Delta編碼搭配,Delta可以很好的将大數值資料變為較小的數值。
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資料壓縮算法,它屬于面向位元組的LZ77壓縮方案家族,壓縮比并不高,它的特點是解碼速度極快。據官方測試基準lzbench的測試結果,預設配置下,解壓速度高達4970MB/s.
Simple8b是64位算法,實作将多個整形資料(在0和1<<60 -1之間)壓縮到一個64位的存儲結構中。其中前4位表示選擇器,後面60位用于存儲資料。優點是簡單高效,定長編碼保證了解壓效率。但對于大整數或者浮動較大的值,壓縮率較低,适用于範圍較小的無符号整數。
LZO是塊壓縮算法,同樣屬于LZ77壓縮方案家族,該算法的目标是快速壓縮和解壓縮,并非壓縮比。相比之下,LZ4的解壓速度更快。由于塊中存放的資料類型可能多種多樣,整體的壓縮效果遠沒有針對某一種資料類型進行壓縮的算法好。
DEFLATE是同時使用了LZ77算法與哈夫曼編碼(Huffman Coding)的一個經典無損資料壓縮算法。實際上deflate隻是一種壓縮資料流的算法。該算法是zip檔案壓縮的預設算法,在gzip,zlib等算法中都有封裝。
Zstandard(Zstd)的設計目的是提供一個類似于DEFLATE算法的壓縮比,但更快,特别是解壓縮。它的壓縮級别從負5級(最快)到22級(壓縮速度最慢,但是壓縮比最高)可以調節。在文本日志壓縮場景中,壓縮性能與LZ4、Snappy相當甚至更好。Linux核心,HTTP協定,Hadoop,HBase等都已經加入對Zstd的支援,可以預見,Zstd将是未來幾年裡被廣泛關注的壓縮算法。
Bit-packing(位壓縮)壓縮算法基于不是所有的整型都需要32位或者64位來存儲這一前提,從我們要壓縮的資料中删除不必要的位。比如一個32位的整型資料,其值的範圍在【0,100】之間,則可以用7位就可以表示。
下表列舉了一些常見的開源時序資料庫和對應采用的資料壓縮算法。
時序資料的業務特征決定了時序資料适合做壓縮,時序資料的資料特征決定了時序資料可以被很好的壓縮。資料壓縮算法的壓縮率和壓縮速度是一對沖突,壓縮率高,必定壓縮速度就會慢,反之亦然,壓縮算法需要根據業務情況在二者之間找到合适的平衡點。資料壓縮率與資料的存儲方式密切相關,實驗表明,行存的壓縮率相比列存的壓縮率差。為了達到更好的壓縮率,華為雲GaussDB(for Influx)時序資料庫采用列式資料存儲,相同資料類型的資料被存放在一起。在壓縮算法層面,自研自适應壓縮算法,針對不同資料類型和資料分布自動适配合适的資料壓縮算法;在算法設計目标層面,資料的壓縮率、壓縮速度、解壓速度需要滿足每天萬億點寫入和海量資料下絕大部分運維監控與IoT場景典型業務的并發查詢性能要求。
不變性:時序資料在寫入後,一般不會被修改。這個特征非常适用于壓縮,不因修改某個資料對整個資料塊進行修改。
時效性:時間越近的資料被通路的機率大,時間越是久遠,資料被通路的機率越低。是以,對于時序的熱資料,可以采用壓縮和解壓速度比較好,壓縮率合理的壓縮算法,而對于冷資料,非常适合使用更高壓縮比的算法。
資料量龐大:時序資料的采集類型豐富, 随着采集硬體的普及和采集頻率增加,使得資料量出現暴增,比如自動駕駛中每輛車每天就會采集将近 8T 的資料,帶寬、實時寫入、快速查詢、存儲、耗電以及維護成本都是挑戰。
資料使用冷熱:使用者可能對某些資料源或者時間段的關注遠遠超過其他,是以在海量資料中偏向某些特殊時間段或某些資料源的資料查詢。
Timestamp:穩定遞增。某些時序資料是固定頻率采樣,例如城市空氣品質檢測儀每分鐘采樣一次pm2.5含量。還有部分時序資料是按照行為變化采樣的,比如股市裡的股價、交易資料、使用者使用行為。
Filed的時間屬性:同一資料源産生的時序資料都因有時間屬性而有了先後順序性和時間間隔屬性。
Filed的取值特性:不同資料源的不同名額值往往歸屬某個區間範圍,比如方向、速度、電壓、溫度等。
Filed的連續性:現實世界的事物是連續變化的,除非突發事件,或者接收資料的傳感器裝置故障,否則同一資料源的資料相鄰時間段内産生的資料比較接近,比如伺服器記憶體名額值的采集。
Filed的周期性:監控資料往往具有周期性或者規律性。
Filed的異常性:裝置故障或突發事件引起的異常性。例如某個新聞事件引起網站流量的激增。
”大道至簡“不僅是生活哲學,也是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倍。
點選關注,第一時間了解華為雲新鮮技術~