簡介
在物聯網(IoT)和工業互聯網(IIoT)大數據應用場景中,實時數據的價值往往遠超歷史數據。企業不僅需要數據處理系統具備高效的實時寫入能力,更需要能快速獲取設備的最新狀態,或者對最新數據進行實時計算和分析。無論是工業設備的狀態監控、車聯網中的車輛位置追蹤,還是智能儀表的實時讀數,當前值都是業務運行中不可或缺的核心數據。這些數據直接關系到生產安全、運營效率以及用戶體驗。
例如,在工業生產中,生產線設備的當前運行狀態至關重要。操作員需要實時監控溫度、壓力、轉速等關鍵指標,一旦設備出現異常,這些數據必須即時呈現,以便迅速調整工藝參數,避免停產或更大的損失。在車聯網領域,以滴滴為例,車輛的實時位置數據是滴滴平臺優化派單策略、提升運營效率的關鍵,確保每位乘客快速上車并享受更高質量的出行體驗。
同時,看板系統和智能儀表作為現場操作和用戶端的窗口,也需要實時數據支撐。無論是工廠管理者通過看板獲取的實時生產指標,還是家庭用戶隨時查詢智能水表、電表的用量,實時性不僅影響到運營和決策效率,更直接關系到用戶對服務的滿意程度。
傳統緩存方案的局限性
為了滿足這些高頻實時查詢需求,許多企業選擇將 Redis 等緩存技術集成到大數據平臺中,通過在數據庫和應用之間添加一層緩存來提升查詢性能。然而,這種方法也帶來了不少問題:
- 系統復雜性增加:需要額外部署和維護緩存集群,對系統架構提出了更高的要求。
- 運營成本上升:需要額外的硬件資源來支撐緩存,增加了維護和管理的開銷。
- 一致性問題:緩存和數據庫之間的數據同步需要額外的機制來保障,否則可能出現數據不一致的情況。
TDengine 的解決方案:內置讀緩存
為了解決這些問題,TDengine 針對物聯網和工業互聯網的高頻實時查詢場景,設計并實現了讀緩存機制。這一機制能夠自動將每張表的最后一條記錄緩存到內存中,從而在不引入第三方緩存技術的情況下,直接滿足用戶對當前值的實時查詢需求。
TDengine 采用時間驅動的緩存管理策略,將最新數據優先存儲在緩存中,查詢時無需訪問硬盤即可快速返回結果。當緩存容量達到設定上限時,系統會批量將最早的數據寫入硬盤,既提升了查詢效率,也有效減少了硬盤的寫入負擔,延長硬件使用壽命。
用戶可通過設置 cachemodel 參數,自定義緩存模式,包括緩存最新一行數據、每列最近的非 NULL 值,或同時緩存行和列的數據。這種靈活設計在物聯網場景中尤為重要,使設備狀態的實時查詢更加高效精準。
這種讀緩存機制的內置化設計顯著降低了查詢延遲,避免了引入 Redis 等外部系統的復雜性和運維成本。同時,減少了頻繁查詢對存儲系統的壓力,大幅提升系統的整體吞吐能力,確保在高并發場景下依然穩定高效運行。通過讀緩存,TDengine 為用戶提供了一種更輕量化的實時數據處理方案,不僅優化了查詢性能,還降低了整體運維成本,為物聯網和工業互聯網用戶提供強有力的技術支持。
TDengine 的讀緩存配置
在創建數據庫時,用戶可以選擇是否啟用緩存機制以存儲該數據庫中每張子表的最新數據。這一緩存機制由數據庫創建參數 cachemodel 進行控制。參數 cachemodel 具有如下 4 種情況:
- none:不緩存
- last_row:緩存子表最近一行數據,這將顯著改善 last_row 函數的性能
- last_value:緩存子表每一列最近的非 NULL 值,這將顯著改善無特殊影響(比如 WHERE、ORDER BY、GROUP BY、INTERVAL)時的 last 函數的性能
- both:同時緩存最近的行和列,即等同于上述 cachemodel 值為 last_row 和 last_value 的行為同時生效
當使用數據庫讀緩存時,可以使用參數 cachesize 來配置每個 vnode 的內存大小。
- cachesize:表示每個 vnode 中用于緩存子表最近數據的內存大小。默認為 1,范圍是 [1,65536],單位是 MB。需要根據機器內存合理配置。
關于數據庫的具體創建,相關參數和操作說明請參考創建數據庫
實時數據查詢的緩存實踐
本節以智能電表為例,來詳細看看 LAST 緩存對實時數據查詢的性能提升。首先使用 taosBenchmark 工具,生成本章內容需要的智能電表的時序數據。
# taosBenchmark -d power -Q --start-timestamp=1600000000000 --tables=10000 --records=10000 --time-step=10000 -y
上面的命令,taosBenchmark 工具在 TDengine 中生成了一個用于測試的 電表數據庫 power,產生共 10 億條時序數據。時序數據的時間戳從 1600000000000(2020-09-13T20:26:40+08:00)
開始,超級表為 meters
,包含 10000 個設備(子表),每個設備有 10000 條數據,時序數據的采集頻率是 10 秒/條。
查詢任意一個電表的最新的電流和時間戳數據,執行如下 SQL
taos> select last(ts, current) from meters;last(ts) | last(current) |
=================================================2020-09-15 00:13:10.000 | 1.1294620 |
Query OK, 1 row(s) in set (0.353815s)taos> select last_row(ts, current) from meters;last_row(ts) | last_row(current) |
=================================================2020-09-15 00:13:10.000 | 1.1294620 |
Query OK, 1 row(s) in set (0.344070s)
希望使用緩存來查詢任意一個電表的最新時間戳數據,執行如下 SQL,并檢查數據庫的緩存生效。
taos> alter database power cachemodel 'both' ;
Query OK, 0 row(s) affected (0.046092s)taos> show create database power\G;
*************************** 1.row ***************************Database: power
Create Database: CREATE DATABASE `power` BUFFER 256 CACHESIZE 1 CACHEMODEL 'both' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 2 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 10 SINGLE_STABLE 0 TABLE_PREFIX 0 TABLE_SUFFIX 0 TSDB_PAGESIZE 4 WAL_RETENTION_PERIOD 3600 WAL_RETENTION_SIZE 0 KEEP_TIME_OFFSET 0
Query OK, 1 row(s) in set (0.000282s)
再次查詢電表的最新的實時數據,第一次查詢會做緩存計算,后續的查詢時延就大大縮減。
taos> select last(ts, current) from meters;last(ts) | last(current) |
=================================================2020-09-15 00:13:10.000 | 1.1294620 |
Query OK, 1 row(s) in set (0.044021s)taos> select last_row(ts, current) from meters;last_row(ts) | last_row(current) |
=================================================2020-09-15 00:13:10.000 | 1.1294620 |
Query OK, 1 row(s) in set (0.046682s)
可以看到查詢的時延從 353/344ms 縮短到了 44ms,提升約 8 倍。
訪問官網
更多內容歡迎訪問 TDengine 官網