時(shí)序數(shù)據(jù)庫作為處理時(shí)間序列數(shù)據(jù)的專業(yè)數(shù)據(jù)庫系統(tǒng),其存儲(chǔ)引擎的設(shè)計(jì)直接決定了數(shù)據(jù)寫入性能、查詢效率和存儲(chǔ)成本。TDengine作為一款專為物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)場景設(shè)計(jì)的時(shí)序數(shù)據(jù)庫,其存儲(chǔ)引擎針對(duì)時(shí)序數(shù)據(jù)的特性進(jìn)行了深度優(yōu)化,實(shí)現(xiàn)了高吞吐寫入、高效查詢和極致壓縮率。本文將深入剖析TDengine存儲(chǔ)引擎的核心原理,包括行列格式編碼、vnode存儲(chǔ)架構(gòu)、LSM樹實(shí)現(xiàn)以及數(shù)據(jù)壓縮技術(shù)。
一、存儲(chǔ)引擎核心競爭力:專為時(shí)序數(shù)據(jù)量身定制
時(shí)序數(shù)據(jù)具有時(shí)間戳遞增、數(shù)據(jù)量大、寫入頻率高、查詢以時(shí)間范圍為主等顯著特征。傳統(tǒng)關(guān)系型數(shù)據(jù)庫的存儲(chǔ)引擎難以高效處理這類數(shù)據(jù),而TDengine存儲(chǔ)引擎從設(shè)計(jì)之初就充分考慮了時(shí)序數(shù)據(jù)的這些特性。
TDengine存儲(chǔ)引擎的核心優(yōu)勢體現(xiàn)在以下幾個(gè)方面:
- 高并發(fā)寫入優(yōu)化:針對(duì)物聯(lián)網(wǎng)場景海量設(shè)備并發(fā)寫入的特點(diǎn),設(shè)計(jì)了高效的寫入路徑
- 時(shí)間范圍查詢優(yōu)化:利用數(shù)據(jù)的時(shí)間有序性,實(shí)現(xiàn)快速的時(shí)間范圍過濾
- 極致壓縮能力:通過差值編碼和專用壓縮算法,將存儲(chǔ)空間降低至原始數(shù)據(jù)的10%以內(nèi)
- 水平擴(kuò)展能力:通過vnode機(jī)制實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)分片和負(fù)載均衡
二、行列格式編碼:靈活應(yīng)對(duì)不同數(shù)據(jù)特征
TDengine支持兩種數(shù)據(jù)編碼格式,以適應(yīng)不同類型的時(shí)序數(shù)據(jù):
2.1 Tuple編碼:非稀疏數(shù)據(jù)的高效存儲(chǔ)
Tuple編碼適用于數(shù)據(jù)密集、非稀疏的場景,其核心特點(diǎn)是:
- O(1)時(shí)間復(fù)雜度訪問:通過行號(hào)直接定位數(shù)據(jù)位置
- 連續(xù)存儲(chǔ):數(shù)據(jù)在磁盤上連續(xù)存放,有利于順序讀取
- 空間效率高:無需額外的索引結(jié)構(gòu)
-- 創(chuàng)建使用Tuple編碼的表
CREATE TABLE device_data (
ts TIMESTAMP,
temperature FLOAT,
humidity FLOAT,
pressure FLOAT
) ENCODE = 'tuple';
在Tuple編碼模式下,每一列的數(shù)據(jù)按行順序連續(xù)存儲(chǔ)。當(dāng)查詢某一行數(shù)據(jù)時(shí),存儲(chǔ)引擎可以通過簡單的偏移量計(jì)算直接定位到數(shù)據(jù)位置,無需遍歷索引。
2.2 Key-Value編碼:稀疏數(shù)據(jù)的靈活方案
對(duì)于稀疏數(shù)據(jù)(即存在大量NULL值的場景),TDengine提供Key-Value編碼:
- offset數(shù)組索引:通過偏移量數(shù)組記錄每行數(shù)據(jù)的實(shí)際位置
- 靈活的空間分配:只為實(shí)際存在的數(shù)據(jù)分配存儲(chǔ)空間
- 適合異構(gòu)設(shè)備:不同設(shè)備上報(bào)的字段不一致時(shí)尤為有效
-- 創(chuàng)建使用Key-Value編碼的表(適合稀疏數(shù)據(jù))
CREATE TABLE sparse_device (
ts TIMESTAMP,
sensor_a FLOAT,
sensor_b FLOAT,
sensor_c FLOAT,
sensor_d FLOAT
) ENCODE = 'kv';
Key-Value編碼通過維護(hù)一個(gè)offset數(shù)組來實(shí)現(xiàn)快速查找。雖然訪問需要一次額外的索引查找,但對(duì)于稀疏數(shù)據(jù)場景,節(jié)省的存儲(chǔ)空間遠(yuǎn)超索引開銷。
三、vnode存儲(chǔ)架構(gòu):三層分離設(shè)計(jì)
TDengine采用vnode(虛擬節(jié)點(diǎn))作為數(shù)據(jù)分片和管理的基本單元。每個(gè)vnode的存儲(chǔ)架構(gòu)分為三個(gè)獨(dú)立部分:
3.1 WAL(Write Ahead Log)
WAL是TDengine保證數(shù)據(jù)持久性的核心機(jī)制:
- 順序?qū)懭?/strong>:所有數(shù)據(jù)變更首先追加寫入WAL
- 崩潰恢復(fù):系統(tǒng)重啟時(shí)通過重放WAL恢復(fù)數(shù)據(jù)
- 異步刷盤:WAL寫入成功后即可返回客戶端,數(shù)據(jù)異步寫入數(shù)據(jù)文件
vnode目錄結(jié)構(gòu)示例:
/vnode/vnodeX/
├── wal/ # WAL文件目錄
│ ├── 000000001.wal
│ ├── 000000002.wal
│ └── ...
├── meta/ # 元數(shù)據(jù)存儲(chǔ)目錄
│ └── tdb/ # TDB引擎數(shù)據(jù)
└── tsdb/ # 時(shí)序數(shù)據(jù)存儲(chǔ)目錄
├── data/ # 數(shù)據(jù)文件
├── head/ # 索引文件
└── sma/ # 預(yù)聚合數(shù)據(jù)
3.2 元數(shù)據(jù)存儲(chǔ)(TDB引擎)
元數(shù)據(jù)采用B+Tree結(jié)構(gòu)的TDB引擎存儲(chǔ):
- 適合讀多寫少:B+Tree在讀取場景下性能優(yōu)異
- 范圍查詢高效:支持表名、標(biāo)簽的范圍掃描
- 事務(wù)支持:保證元數(shù)據(jù)操作的原子性
元數(shù)據(jù)包括超級(jí)表定義、子表信息、標(biāo)簽數(shù)據(jù)等,這類數(shù)據(jù)的特點(diǎn)是寫入頻率低但查詢頻繁,B+Tree結(jié)構(gòu)正好契合這一訪問模式。
3.3 時(shí)序數(shù)據(jù)存儲(chǔ)(TSDB引擎)
時(shí)序數(shù)據(jù)采用專門的TSDB引擎,基于LSM樹結(jié)構(gòu)實(shí)現(xiàn),這是TDengine存儲(chǔ)引擎的核心。
四、時(shí)序數(shù)據(jù)存儲(chǔ):LSM樹結(jié)構(gòu)深度解析
TDengine的TSDB引擎采用LSM(Log-Structured Merge)樹架構(gòu),這是業(yè)界處理高并發(fā)寫入的標(biāo)準(zhǔn)方案。
4.1 MemTable:內(nèi)存中的有序結(jié)構(gòu)
MemTable是數(shù)據(jù)寫入的第一站,TDengine采用雙數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn):
紅黑樹(Red-Black Tree):
- 用于維護(hù)數(shù)據(jù)的唯一性和有序性
- 保證O(log n)的插入和查找復(fù)雜度
- 自動(dòng)處理同一時(shí)間戳的數(shù)據(jù)去重
SkipList(跳表):
- 用于高效的范圍查詢
- 支持多層級(jí)索引,查詢復(fù)雜度O(log n)
- 實(shí)現(xiàn)簡單,并發(fā)性能優(yōu)異
// MemTable結(jié)構(gòu)示意
typedef struct SMemTable {
SRBTree rbtree; // 紅黑樹:去重和排序
SSkipList *skiplist; // 跳表:范圍查詢
int64_t size; // 當(dāng)前數(shù)據(jù)大小
int64_t maxSize; // 刷盤閾值
} SMemTable;
當(dāng)MemTable達(dá)到預(yù)設(shè)大小閾值時(shí),會(huì)被凍結(jié)并轉(zhuǎn)換為不可變的IMemTable,隨后后臺(tái)線程將其刷寫到磁盤。
4.2 數(shù)據(jù)文件組:分層存儲(chǔ)的實(shí)現(xiàn)
TDengine將磁盤數(shù)據(jù)組織為文件組(File Group),每個(gè)文件組包含以下文件:
| 文件類型 | 擴(kuò)展名 | 功能說明 |
|---|---|---|
| Head文件 | .head | 存儲(chǔ)數(shù)據(jù)塊的索引信息,用于快速定位 |
| Data文件 | .data | 存儲(chǔ)實(shí)際的時(shí)序數(shù)據(jù),按列壓縮存儲(chǔ) |
| SMA文件 | .sma | 存儲(chǔ)預(yù)聚合數(shù)據(jù)(Simple Moving Average) |
| Tomb文件 | .tomb | 存儲(chǔ)刪除標(biāo)記,支持?jǐn)?shù)據(jù)軟刪除 |
| STT文件 | .stt | 存儲(chǔ)小文件合并的臨時(shí)數(shù)據(jù) |
文件組結(jié)構(gòu)示例:
v2f1800.head # 版本2,文件組1800的索引
v2f1800.data # 版本2,文件組1800的數(shù)據(jù)
v2f1800.sma # 版本2,文件組1800的預(yù)聚合
v2f1800.tomb # 版本2,文件組1800的刪除標(biāo)記
v2f1800.stt # 版本2,文件組1800的臨時(shí)數(shù)據(jù)
4.3 Compaction:數(shù)據(jù)整理與優(yōu)化
LSM樹的核心機(jī)制是Compaction(合并),TDengine實(shí)現(xiàn)了多層級(jí)合并策略:
- Level 0:MemTable刷盤產(chǎn)生的新文件
- Level 1-N:隨著合并層級(jí)增加,文件越來越大
- Tiered Compaction:按時(shí)間分層,舊數(shù)據(jù)合并為大文件
- Leveled Compaction:按大小分層,同層文件大小相近
Compaction過程中,TDengine會(huì):
- 合并多個(gè)小文件,減少文件句柄開銷
- 清理被刪除的數(shù)據(jù)(基于tomb文件)
- 重新壓縮數(shù)據(jù),提高壓縮率
- 更新索引,優(yōu)化查詢性能
五、數(shù)據(jù)壓縮:差值編碼與通用壓縮結(jié)合
時(shí)序數(shù)據(jù)的壓縮是TDengine存儲(chǔ)引擎的一大亮點(diǎn),通過多級(jí)壓縮策略實(shí)現(xiàn)極致的壓縮率。
5.1 差值編碼(Delta Encoding)
針對(duì)時(shí)間戳列,TDengine采用差值編碼:
原始時(shí)間戳: 1000, 1010, 1020, 1030, 1040, 1050
差值編碼后: 1000, 10, 10, 10, 10, 10
由于時(shí)序數(shù)據(jù)的時(shí)間戳通常是等間隔或近似等間隔的,差值編碼可以將大整數(shù)轉(zhuǎn)換為小整數(shù),大幅降低存儲(chǔ)空間。
5.2 通用壓縮算法
在差值編碼基礎(chǔ)上,TDengine支持多種通用壓縮算法:
- LZ4:壓縮和解壓速度快,適合CPU敏感場景
- ZSTD:壓縮率更高,適合存儲(chǔ)成本敏感場景
- XZ:極致壓縮率,適合冷數(shù)據(jù)歸檔
-- 創(chuàng)建表時(shí)指定壓縮算法
CREATE TABLE metrics (
ts TIMESTAMP,
value DOUBLE
) COMPRESS = 'zstd';
5.3 壓縮效果
通過差值編碼與通用壓縮的結(jié)合,TDengine在實(shí)際生產(chǎn)環(huán)境中通常能達(dá)到:
- 時(shí)間戳列:壓縮率可達(dá)5%以下
- 數(shù)值列:根據(jù)數(shù)據(jù)特征,壓縮率10%-30%
- 整體壓縮率:典型場景下可達(dá)原始數(shù)據(jù)的10%以內(nèi)
六、總結(jié)
TDengine時(shí)序數(shù)據(jù)庫的存儲(chǔ)引擎通過精心設(shè)計(jì)的架構(gòu),實(shí)現(xiàn)了高吞吐寫入、高效查詢和極致壓縮的完美結(jié)合。其核心設(shè)計(jì)亮點(diǎn)包括:
- 靈活的行列編碼:Tuple編碼適合密集數(shù)據(jù),Key-Value編碼適合稀疏數(shù)據(jù)
- 三層存儲(chǔ)分離:WAL保證持久性,TDB管理元數(shù)據(jù),TSDB處理時(shí)序數(shù)據(jù)
- LSM樹優(yōu)化:紅黑樹+SkipList的MemTable設(shè)計(jì),多層級(jí)Compaction策略
- 極致壓縮:差值編碼結(jié)合通用壓縮算法,壓縮率可達(dá)10%以內(nèi)
對(duì)于需要處理海量時(shí)序數(shù)據(jù)的物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)、金融監(jiān)控等場景,TDengine的存儲(chǔ)引擎提供了業(yè)界領(lǐng)先的性能表現(xiàn)和存儲(chǔ)效率。無論是每秒數(shù)百萬點(diǎn)的寫入吞吐,還是PB級(jí)數(shù)據(jù)的存儲(chǔ)管理,TDengine都能提供穩(wěn)定可靠的技術(shù)支撐。
關(guān)于TDengine:TDengine是由濤思數(shù)據(jù)開發(fā)的開源時(shí)序數(shù)據(jù)庫,專為物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)、車聯(lián)網(wǎng)等場景設(shè)計(jì),具有高性能、高壓縮率、易擴(kuò)展等特點(diǎn)。了解更多信息,請?jiān)L問TDengine官網(wǎng)。



互聯(lián)網(wǎng).png)



-1.png)




.png)


證.png)


伙伴.png)
伙伴.png)
伙伴.png)



