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