小 T 導讀:昆嶽互聯的“a環保”APP基於自主打造的環保產業互聯網平臺(INECO平臺),對環境基礎設施海量數據實時處理與分析,可以秒級實時採集工業大氣環保各項監控指標的數據,分別通過年、月、日三個維度,結合不同的採集頻率週期,對採集到的海量數據進行分析、展示,在時序數據庫的選型中,經過對比,最終選擇了TDengine。
程序設計
整個數據採集服務基於MQTT協議開發,通過阿里巴巴的nacos集羣實現配置和服務發現,通過feign模式調用其他微服務模塊的業務數據,來對上報的數據進行業務解析,並將解析的結果存入對應監控指標對應的點位表中。採集服務採用mybatis-plus的多數據源配置,使用的是目前性能最佳的HikariCP數據連接池,分別配置MySQL和TDengine兩個數據庫連接,實現了多數據源的無縫切換。整個採集服務基於容器化部署,採用Kubernetes進行容器編排,通過分佈式鎖方式避免了數據重複入庫,提高了數據的解析速度,實現MQTT的分佈式分組採集。
數據庫選型
我們公司對比了阿里的時序時空數據庫TSDB、傳統的 MySQL 以及 TDengine。
與傳統數據庫對比
-
MySQL :查詢效率低,需要按數據時間分庫分表,應用場景不合適,沒有基於採集頻率週期的高效查詢。
-
TDengine :查詢效率高,不需要分表,具備時間維度聚合、流式計算、緩存等特性。
數據庫 | 查詢效率 | 應用場景 | 流式計算 |
---|---|---|---|
MySQL | 低 | 事務型 | 不支持 |
TDengine | 高 | 時序型 | 支持 |
與其他時序庫對比
-
阿里TSDB :閉源,私有化落地比較難
-
TDengine :性價比高,開源,支持雲端和本地部署
尤其是TDengine一張設備一張表的建表思路,和我們的程序設計方式非常契合。同時TDengine還有一個超級表的設計,可以給不同的設備打上標籤,比如客戶ID、設備ID、指標名稱等等,管理多條時間線變得非常方便。整個數據庫也是SQL交互方式,支持標準JDBC接口,可以無縫對接MyBastis ORM框架,開發起來非常方便。因此我們最終選用了TDengine雲服務作爲各項監控指標的存儲數據庫,並且花了大概一週時間就上線了系統。
建表思路
我們目前是通過超級表的模式來進行數據建表,我們子表是point_#{採集點唯一編碼} 。標籤對應爲客戶唯一標識、設備唯一標識、採集指標編號、指標名稱、計量單位名稱。
建立超級表
create table point(ts timestamp,val float,flag bool) tags(cusid bigint, devid bigint, code bigint, pointname binary(20),unitname binary(20));
根據超級表建立子表
create table point_0301 using point tags(10000000, 301, 107, 'DUST', 'mg/Nm3');
create table point_0302 using point tags(10000000, 302, 107, 'DUST', 'mg/Nm3');
...
這樣的設計很自然的對採集數據進行了分表。而在查詢時,可以從超級表進行查詢,無需針對每張子表進行。此外,在超級表查詢時,還可以按照客戶、採集量等去篩選具體業務需要的子表出來。超級表的標籤相當於對子表加了一個索引,非常方便。超級表的標籤是支持增刪改查的,這對我們目前尚未定型的業務邏輯是個大好消息:在後面業務需要發生變化時,比如需要爲各個設備增加一個“城市”的分析維度,我們也不再需要重新更新一遍所有數據,而只用直接爲每個表增加一個標籤即可。
方便的流式計算
時間維度聚合
業務需要對原始的秒級採集數據進行年、月、日、分鐘等的聚合計算和繪圖。這個需求可以直接在TDengine中按照時間進行將採樣查詢解決。在計算超標濃度的時候,需要對每分鐘的平均值進行實時計算監控。比如污染排放的監控中,業務要求對NOx的濃度實時監控,並且讓用戶選擇時間範圍顯示濃度變化曲線以及聚合的窗口長度(5分鐘、15分鐘、30分鐘、日、月、年)。由於傳到前端的數據是時序數據庫已經計算好的,數據量一般沒有那麼大,相比把所有原始數據點都拉到前端再處理而言,效率大大提高。
00:00:00.000' and ts>'2020-05-29 00:00:00.000' interval(5m); //每5分鐘聚合
select val from point_0301 where ts<'2020-05-30 00:00:00.000' and ts>'2020-05-29 00:00:00.000' interval(15m); //每15分鐘聚合
select val from point_0301 where ts<'2020-05-30 00:00:00.000' and ts>'2020-05-29 00:00:00.000' interval(30m); //每30分鐘聚合
流式計算
對於每分鐘的平均量進行實時計算,只需要簡單的定義時間窗口和滑動增量,數據庫就能返回每分鐘的平均量。對於實時監測、預警的指標,可以專門爲這類數據建立流計算,並將計算結果寫入新的表(如下strm_pt_0304)中存儲,這樣整個實時計算的結果也可以做歷史回顧。
create table strm_pt_0304 as select avg(val) from point_0304 INTERVAL(1m) SLIDING(1m);//每分鐘計算一次每分鐘的平均值
原本很多需要在程序中處理的數值計算,現在完全都由TDengine承擔,一方面分擔了程序的計算壓力,另一方面更重要的是,聚合結果可以自動持久化存儲,支持歷史數據即時回看。
對TDengine的體驗總結
開源版的TDengine可以做本地測試適配,安裝包只有5MB,使用非常方便,各種接口也和企業版完全一致。但希望可以對購買企業版的客戶,提供一個可以兼容開源版本的web版查詢工具,方便調試。
現在TDengine對Java驅動的支持已經相當好,但希望可以提供更多.net core版本的驅動支持。
作者介紹:
王飛,昆嶽互聯物聯網技術專家,有多年.net/Java軟件設計開發經驗、熟悉工業級監控、環境監控等業務建模,主導了昆嶽互聯“A環保”項目的整體設計、開發工作。