編碼和壓縮
編碼和壓縮
編碼方式
基本編碼方式
為了提高數(shù)據(jù)的存儲效率,需要在數(shù)據(jù)寫入的過程中對數(shù)據(jù)進(jìn)行編碼,從而減少磁盤空間的使用量。在寫數(shù)據(jù)以及讀數(shù)據(jù)的過程中都能夠減少 I/O 操作的數(shù)據(jù)量從而提高性能。IoTDB 支持多種針對不同類型的數(shù)據(jù)的編碼方法:
PLAIN 編碼(PLAIN)
PLAIN 編碼,默認(rèn)的編碼方式,即不編碼,支持多種數(shù)據(jù)類型,壓縮和解壓縮的時間效率較高,但空間存儲效率較低。
二階差分編碼(TS_2DIFF)
二階差分編碼,比較適合編碼單調(diào)遞增或者遞減的序列數(shù)據(jù),不適合編碼波動較大的數(shù)據(jù)。
游程編碼(RLE)
游程編碼,比較適合存儲某些數(shù)值連續(xù)出現(xiàn)的序列,不適合編碼大部分情況下前后值不一樣的序列數(shù)據(jù)。
游程編碼也可用于對浮點(diǎn)數(shù)進(jìn)行編碼,但在創(chuàng)建時間序列的時候需指定保留小數(shù)位數(shù)(MAX_POINT_NUMBER,具體指定方式參見本文 SQL 參考文檔)。比較適合存儲某些浮點(diǎn)數(shù)值連續(xù)出現(xiàn)的序列數(shù)據(jù),不適合存儲對小數(shù)點(diǎn)后精度要求較高以及前后波動較大的序列數(shù)據(jù)。
游程編碼(RLE)和二階差分編碼(TS_2DIFF)對 float 和 double 的編碼是有精度限制的,默認(rèn)保留 2 位小數(shù)。推薦使用 GORILLA。
GORILLA 編碼(GORILLA)
GORILLA 編碼是一種無損編碼,它比較適合編碼前后值比較接近的數(shù)值序列,不適合編碼前后波動較大的數(shù)據(jù)。
當(dāng)前系統(tǒng)中存在兩個版本的 GORILLA 編碼實(shí)現(xiàn),推薦使用
GORILLA,不推薦使用GORILLA_V1(已過時)。使用限制:使用 Gorilla 編碼 INT32 數(shù)據(jù)時,需要保證序列中不存在值為
Integer.MIN_VALUE的數(shù)據(jù)點(diǎn);使用 Gorilla 編碼 INT64 數(shù)據(jù)時,需要保證序列中不存在值為Long.MIN_VALUE的數(shù)據(jù)點(diǎn)。字典編碼 (DICTIONARY)
字典編碼是一種無損編碼。它適合編碼基數(shù)小的數(shù)據(jù)(即數(shù)據(jù)去重后唯一值數(shù)量小)。不推薦用于基數(shù)大的數(shù)據(jù)。
ZIGZAG 編碼
ZigZag編碼將有符號整型映射到無符號整型,適合比較小的整數(shù)。
CHIMP 編碼
CHIMP 是一種無損編碼。它是一種新的流式浮點(diǎn)數(shù)據(jù)壓縮算法,可以節(jié)省存儲空間。這個編碼適用于前后值比較接近的數(shù)值序列,對波動小和隨機(jī)噪聲少的序列數(shù)據(jù)更加友好。
使用限制:如果對 INT32 類型數(shù)據(jù)使用 CHIMP 編碼,需要確保數(shù)據(jù)點(diǎn)中沒有
Integer.MIN_VALUE。 如果對 INT64 類型數(shù)據(jù)使用 CHIMP 編碼,需要確保數(shù)據(jù)點(diǎn)中沒有Long.MIN_VALUE。SPRINTZ 編碼
SPRINTZ編碼是一種無損編碼,將原始時序數(shù)據(jù)分別進(jìn)行預(yù)測、Zigzag編碼、位填充和游程編碼。SPRINTZ編碼適合差分值的絕對值較小(即波動較小)的時序數(shù)據(jù),不適合差分值較大(即波動較大)的時序數(shù)據(jù)。
RLBE 編碼
RLBE編碼是一種無損編碼,將差分編碼,位填充編碼,游程長度,斐波那契編碼和拼接等編碼思想結(jié)合到一起。RLBE編碼適合遞增且遞增值較小的時序數(shù)據(jù),不適合波動較大的時序數(shù)據(jù)。
數(shù)據(jù)類型與編碼的對應(yīng)關(guān)系
前文介紹的五種編碼適用于不同的數(shù)據(jù)類型,若對應(yīng)關(guān)系錯誤,則無法正確創(chuàng)建時間序列。數(shù)據(jù)類型與支持其編碼的編碼方式對應(yīng)關(guān)系總結(jié)如下表所示。
| 數(shù)據(jù)類型 | 推薦編碼(默認(rèn)) | 支持的編碼 |
|---|---|---|
| BOOLEAN | RLE | PLAIN, RLE |
| INT32 | TS_2DIFF | PLAIN, RLE, TS_2DIFF, GORILLA, ZIGZAG, CHIMP, SPRINTZ, RLBE |
| DATE | TS_2DIFF | PLAIN, RLE, TS_2DIFF, GORILLA, ZIGZAG, CHIMP, SPRINTZ, RLBE |
| INT64 | TS_2DIFF | PLAIN, RLE, TS_2DIFF, GORILLA, ZIGZAG, CHIMP, SPRINTZ, RLBE |
| TIMESTAMP | TS_2DIFF | PLAIN, RLE, TS_2DIFF, GORILLA, ZIGZAG, CHIMP, SPRINTZ, RLBE |
| FLOAT | GORILLA | PLAIN, RLE, TS_2DIFF, GORILLA, CHIMP, SPRINTZ, RLBE |
| DOUBLE | GORILLA | PLAIN, RLE, TS_2DIFF, GORILLA, CHIMP, SPRINTZ, RLBE |
| TEXT | PLAIN | PLAIN, DICTIONARY |
| STRING | PLAIN | PLAIN, DICTIONARY |
| BLOB | PLAIN | PLAIN |
當(dāng)用戶輸入的數(shù)據(jù)類型與編碼方式不對應(yīng)時,系統(tǒng)會提示錯誤。如下所示,二階差分編碼不支持布爾類型:
IoTDB> create timeseries root.ln.wf02.wt02.status WITH DATATYPE=BOOLEAN, ENCODING=TS_2DIFF
Msg: 507: encoding TS_2DIFF does not support BOOLEAN壓縮方式
當(dāng)時間序列寫入并按照指定的類型編碼為二進(jìn)制數(shù)據(jù)后,IoTDB 會使用壓縮技術(shù)對該數(shù)據(jù)進(jìn)行壓縮,進(jìn)一步提升空間存儲效率。雖然編碼和壓縮都旨在提升存儲效率,但編碼技術(shù)通常只適合特定的數(shù)據(jù)類型(如二階差分編碼只適合與 INT32 或者 INT64 編碼,存儲浮點(diǎn)數(shù)需要先將他們乘以 10m 以轉(zhuǎn)換為整數(shù)),然后將它們轉(zhuǎn)換為二進(jìn)制流。壓縮方式(SNAPPY)針對二進(jìn)制流進(jìn)行壓縮,因此壓縮方式的使用不再受數(shù)據(jù)類型的限制。
基本壓縮方式
IoTDB 允許在創(chuàng)建一個時間序列的時候指定該列的壓縮方式。現(xiàn)階段 IoTDB 支持以下幾種壓縮方式:
- UNCOMPRESSED(不壓縮)
- SNAPPY 壓縮
- LZ4 壓縮(推薦壓縮方式)
- GZIP 壓縮
- ZSTD 壓縮
- LZMA2 壓縮
壓縮方式的指定語法詳見本文SQL 參考文檔。
壓縮比統(tǒng)計(jì)信息
壓縮比統(tǒng)計(jì)信息文件:data/datanode/system/compression_ratio
- ratio_sum: memtable壓縮比的總和
- memtable_flush_time: memtable刷盤的總次數(shù)
通過 ratio_sum / memtable_flush_time 可以計(jì)算出平均壓縮比