在時(shí)序數(shù)據(jù)庫(kù)的應(yīng)用實(shí)踐中,原始數(shù)據(jù)的存儲(chǔ)與查詢(xún)只是基礎(chǔ)能力,越來(lái)越多的業(yè)務(wù)場(chǎng)景要求在數(shù)據(jù)寫(xiě)入的同時(shí)完成實(shí)時(shí)計(jì)算。無(wú)論是數(shù)據(jù)分級(jí)存儲(chǔ)與智能降采樣、預(yù)計(jì)算加速實(shí)時(shí)決策,還是異常檢測(cè)和低延遲告警,都對(duì)系統(tǒng)的流式處理能力提出了更高要求。本文將深入解析時(shí)序數(shù)據(jù)庫(kù)內(nèi)置的流計(jì)算引擎,展示它如何以 SQL 驅(qū)動(dòng)的方式替代傳統(tǒng)流處理框架。
傳統(tǒng)流計(jì)算方案的痛點(diǎn)
在典型的時(shí)序數(shù)據(jù)處理架構(gòu)中,實(shí)現(xiàn)流計(jì)算通常需要部署 Kafka 作為數(shù)據(jù)緩沖層,再接入 Flink 或 Spark Streaming 等流處理框架。這套組合雖然功能強(qiáng)大,但在實(shí)際落地中面臨諸多挑戰(zhàn):
- 高昂的開(kāi)發(fā)成本:需要編寫(xiě) Java/Scala 程序,定義復(fù)雜的算子鏈和數(shù)據(jù)流拓?fù)?/li>
- 繁重的運(yùn)維負(fù)擔(dān):Kafka 集群和 Flink 集群各自需要獨(dú)立的監(jiān)控、調(diào)優(yōu)和故障恢復(fù)機(jī)制
- 數(shù)據(jù)鏈路冗長(zhǎng):數(shù)據(jù)從數(shù)據(jù)庫(kù)寫(xiě)入到 Kafka,再由 Flink 消費(fèi)計(jì)算,最終結(jié)果寫(xiě)回?cái)?shù)據(jù)庫(kù),鏈路長(zhǎng)、延遲高
- 技術(shù)棧碎片化:數(shù)據(jù)存儲(chǔ)用一種技術(shù),流計(jì)算用另一種,團(tuán)隊(duì)需要掌握多套技術(shù)體系
對(duì)于以時(shí)序數(shù)據(jù)為核心業(yè)務(wù)的團(tuán)隊(duì)而言,如果流計(jì)算的需求主要集中在數(shù)據(jù)變換、聚合和異常檢測(cè)等常見(jiàn)場(chǎng)景,引入完整的流處理框架往往是過(guò)度設(shè)計(jì)。
內(nèi)置流計(jì)算引擎的核心設(shè)計(jì)
TDengine 的流計(jì)算引擎采用了一種極簡(jiǎn)而強(qiáng)大的設(shè)計(jì)理念:使用 SQL 定義實(shí)時(shí)流變換。當(dāng)數(shù)據(jù)被寫(xiě)入流的源表后,數(shù)據(jù)會(huì)被以定義的方式自動(dòng)處理,并根據(jù)定義的觸發(fā)模式向目的表推送結(jié)果。在高吞吐數(shù)據(jù)寫(xiě)入下,系統(tǒng)能夠提供毫秒級(jí)的計(jì)算結(jié)果延遲。
這種 SQL 驅(qū)動(dòng)的方式帶來(lái)了顯著的優(yōu)勢(shì):
- 低學(xué)習(xí)成本:熟悉 SQL 的開(kāi)發(fā)人員即可上手,無(wú)需學(xué)習(xí)新的流處理編程模型
- 聲明式定義:用 SQL 描述”要計(jì)算什么”,而非”如何計(jì)算”,引擎自動(dòng)優(yōu)化執(zhí)行計(jì)劃
- 與存儲(chǔ)無(wú)縫集成:計(jì)算結(jié)果直接寫(xiě)入數(shù)據(jù)庫(kù)中的目標(biāo)表,無(wú)需跨系統(tǒng)數(shù)據(jù)搬運(yùn)
三大核心擴(kuò)展能力
與簡(jiǎn)單的連續(xù)查詢(xún)不同,內(nèi)置流計(jì)算引擎在三個(gè)維度上進(jìn)行了深度擴(kuò)展,使其能夠覆蓋更廣泛的業(yè)務(wù)場(chǎng)景。
1. 處理對(duì)象的擴(kuò)展:觸發(fā)與計(jì)算分離
在傳統(tǒng)流計(jì)算中,觸發(fā)計(jì)算的數(shù)據(jù)源和參與計(jì)算的數(shù)據(jù)源通常是同一個(gè)。而內(nèi)置流計(jì)算引擎支持觸發(fā)與計(jì)算分離——觸發(fā)表與計(jì)算的數(shù)據(jù)源表可以不相同。
例如,可以配置為:當(dāng)表 A 寫(xiě)入新數(shù)據(jù)時(shí)觸發(fā)計(jì)算,但計(jì)算的數(shù)據(jù)來(lái)源是表 B。這種解耦設(shè)計(jì)使得業(yè)務(wù)可以靈活定義計(jì)算邏輯的觸發(fā)條件,而不受數(shù)據(jù)來(lái)源的限制。
2. 觸發(fā)方式的擴(kuò)展:多種窗口與過(guò)濾
引擎支持豐富的觸發(fā)方式,滿(mǎn)足不同時(shí)間語(yǔ)義的業(yè)務(wù)需求:
- 窗口觸發(fā):基于固定時(shí)間窗口或滑動(dòng)窗口觸發(fā)計(jì)算
- 定時(shí)觸發(fā):按固定時(shí)間間隔觸發(fā),適合周期性統(tǒng)計(jì)報(bào)表
- 會(huì)話(huà)窗口觸發(fā):基于活動(dòng)間隔劃分會(huì)話(huà),適用于用戶(hù)行為分析
- 狀態(tài)窗口觸發(fā):根據(jù)數(shù)據(jù)狀態(tài)變化劃分窗口
- 事件窗口觸發(fā):由特定事件驅(qū)動(dòng)計(jì)算
- 計(jì)數(shù)窗口觸發(fā):按數(shù)據(jù)條數(shù)達(dá)到閾值觸發(fā)
此外,系統(tǒng)支持對(duì)觸發(fā)數(shù)據(jù)進(jìn)行預(yù)先過(guò)濾(PRE_FILTER),在數(shù)據(jù)進(jìn)入計(jì)算邏輯之前就剔除無(wú)關(guān)記錄,減少不必要的計(jì)算開(kāi)銷(xiāo)。
3. 計(jì)算范圍的擴(kuò)展:跨表跨庫(kù)計(jì)算
流計(jì)算既可以對(duì)觸發(fā)表本身進(jìn)行計(jì)算,也可以對(duì)其他庫(kù)表的數(shù)據(jù)進(jìn)行計(jì)算。更重要的是,它支持任何合法的查詢(xún)語(yǔ)句,包括聚合、關(guān)聯(lián)、標(biāo)量計(jì)算等,賦予了業(yè)務(wù)極大的表達(dá)自由度。
觸發(fā)動(dòng)作的靈活配置
計(jì)算完成后,結(jié)果的輸出方式同樣靈活,支持三種觸發(fā)動(dòng)作:
- 只通知不計(jì)算:通過(guò) WebSocket 推送通知,適合輕量級(jí)的實(shí)時(shí)告警場(chǎng)景
- 只計(jì)算不通知:將計(jì)算結(jié)果寫(xiě)入輸出表,適合預(yù)聚合和數(shù)據(jù)降采樣
- 既通知又計(jì)算:同時(shí)推送通知并寫(xiě)入結(jié)果表,適合需要即時(shí)響應(yīng)且需要持久化結(jié)果的場(chǎng)景
關(guān)鍵控制選項(xiàng)
流計(jì)算引擎提供了豐富的控制參數(shù),幫助開(kāi)發(fā)者精細(xì)調(diào)優(yōu)計(jì)算行為:
| 參數(shù) | 說(shuō)明 |
|---|---|
| WATERMARK | 定義數(shù)據(jù)延遲容忍度,處理亂序數(shù)據(jù) |
| EXPIRED_TIME | 窗口過(guò)期時(shí)間,控制計(jì)算結(jié)果的保留周期 |
| IGNORE_DISORDER | 是否忽略亂序數(shù)據(jù) |
| DELETE_OUTPUT_TABLE | 是否在流刪除時(shí)自動(dòng)清理輸出表 |
| FILL_HISTORY | 是否對(duì)流創(chuàng)建前的歷史數(shù)據(jù)進(jìn)行回填計(jì)算 |
| LOW_LATENCY_CALC | 啟用低延遲計(jì)算模式 |
| PRE_FILTER | 觸發(fā)數(shù)據(jù)的預(yù)過(guò)濾條件 |
| MAX_DELAY | 最大允許延遲,平衡延遲與吞吐 |
其中,WATERMARK 和 IGNORE_DISORDER 是處理工業(yè)場(chǎng)景中常見(jiàn)的數(shù)據(jù)亂序問(wèn)題的關(guān)鍵參數(shù)。在設(shè)備網(wǎng)絡(luò)不穩(wěn)定、數(shù)據(jù)上報(bào)延遲差異較大的情況下,合理配置這兩個(gè)參數(shù)可以有效避免因亂序數(shù)據(jù)導(dǎo)致的計(jì)算結(jié)果不準(zhǔn)確。
FILL_HISTORY 選項(xiàng)則解決了流計(jì)算的一個(gè)常見(jiàn)痛點(diǎn):流創(chuàng)建之前的歷史數(shù)據(jù)是否需要納入計(jì)算。啟用該選項(xiàng)后,引擎會(huì)對(duì)歷史數(shù)據(jù)進(jìn)行回填,確保計(jì)算結(jié)果的完整性。
高可用架構(gòu):存算分離與負(fù)載均衡
在生產(chǎn)環(huán)境中,流計(jì)算任務(wù)的高可用性至關(guān)重要。內(nèi)置流計(jì)算引擎支持流的存算分離架構(gòu):
- snode(Stream Node):負(fù)責(zé)運(yùn)行流計(jì)算任務(wù),是獨(dú)立的計(jì)算節(jié)點(diǎn)
- 多 snode 負(fù)載均衡:多個(gè) snode 之間自動(dòng)分配流計(jì)算任務(wù),避免單點(diǎn)過(guò)載
- 互為副本:snode 之間互為副本,當(dāng)某個(gè)節(jié)點(diǎn)故障時(shí),其他節(jié)點(diǎn)自動(dòng)接管其計(jì)算任務(wù)
這種架構(gòu)設(shè)計(jì)使得流計(jì)算能力可以獨(dú)立于存儲(chǔ)節(jié)點(diǎn)進(jìn)行水平擴(kuò)展,根據(jù)計(jì)算負(fù)載的變化靈活調(diào)整 snode 數(shù)量,同時(shí)保證計(jì)算任務(wù)的持續(xù)可用。
連續(xù)異常檢測(cè)
異常檢測(cè)是工業(yè)互聯(lián)網(wǎng)場(chǎng)景中的核心需求之一。流計(jì)算引擎支持通過(guò)調(diào)用異常檢測(cè)服務(wù)實(shí)現(xiàn)連續(xù)異常檢測(cè),使用 ANOMALY_WINDOW 函數(shù)對(duì)數(shù)據(jù)流進(jìn)行實(shí)時(shí)異常分析。
具體而言,可以在流計(jì)算的定義中嵌入異常檢測(cè)邏輯,當(dāng)數(shù)據(jù)流經(jīng)計(jì)算管道時(shí),自動(dòng)對(duì)指定窗口內(nèi)的數(shù)據(jù)進(jìn)行異常評(píng)分或分類(lèi)。結(jié)合前面提到的 WebSocket 通知機(jī)制,一旦檢測(cè)到異常,可以立即推送告警,實(shí)現(xiàn)端到端的實(shí)時(shí)異常響應(yīng)。
與傳統(tǒng)方案對(duì)比
| 維度 | 內(nèi)置流計(jì)算 | Kafka + Flink |
|---|---|---|
| 定義方式 | SQL | Java/Scala 程序 |
| 部署組件 | 僅數(shù)據(jù)庫(kù) | Kafka + Flink + 數(shù)據(jù)庫(kù) |
| 運(yùn)維復(fù)雜度 | 低 | 高 |
| 數(shù)據(jù)鏈路 | 數(shù)據(jù)庫(kù)內(nèi)部 | 跨系統(tǒng) |
| 學(xué)習(xí)成本 | SQL 即可 | 需掌握流處理框架 |
| 結(jié)果存儲(chǔ) | 直接寫(xiě)入庫(kù)表 | 需要回寫(xiě)數(shù)據(jù)庫(kù) |
需要指出的是,內(nèi)置流計(jì)算引擎并非要替代所有場(chǎng)景下的 Kafka + Flink 方案。對(duì)于需要復(fù)雜事件處理(CEP)、多流 Join、跨異構(gòu)數(shù)據(jù)源等高級(jí)需求的場(chǎng)景,傳統(tǒng)流處理框架仍然有其優(yōu)勢(shì)。但對(duì)于以時(shí)序數(shù)據(jù)為核心、計(jì)算邏輯以聚合和變換為主的典型物聯(lián)網(wǎng)和工業(yè)場(chǎng)景,內(nèi)置流計(jì)算引擎在簡(jiǎn)潔性和效率上具有明顯優(yōu)勢(shì)。
結(jié)語(yǔ)
流計(jì)算是時(shí)序數(shù)據(jù)處理從”存得好”邁向”算得快”的關(guān)鍵一步。TDengine 的流計(jì)算引擎以 SQL 為核心接口,通過(guò)觸發(fā)與計(jì)算分離、多種窗口類(lèi)型、跨表跨庫(kù)計(jì)算等擴(kuò)展能力,覆蓋了物聯(lián)網(wǎng)和工業(yè)互聯(lián)網(wǎng)場(chǎng)景中的主流流計(jì)算需求。結(jié)合存算分離的高可用架構(gòu)和毫秒級(jí)計(jì)算延遲,這套方案能夠在不增加系統(tǒng)復(fù)雜度的前提下,為企業(yè)提供生產(chǎn)級(jí)的實(shí)時(shí)計(jì)算能力。



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



-1.png)




.png)


證.png)


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



