作者:西門子 鄧厲波
摘要:SIMICAS® OEM 設備遠程運維套件是由 SIEMENS DE&DS DSM 團隊開發的一套面向設備制造商的數字化解決方案。在确定選擇 TDengine 作為系統的時序數據庫後,他們在 SIMICAS® OEM 2.0 版本中移除了 Flink、Kafka 以及 Redis,大大簡化了系統架構。
項目背景
IIoT(Industrial Internet of Things)是工業物聯網的簡稱,它将具有感知、監控能力的各類采集、控制傳感器或控制器,以及移動通信、智能分析等技術不斷融入到工業生産過程的各個環節,從而大幅提高制造效率,改善産品質量,降低産品成本和資源消耗,最終實現将傳統工業提升到智能化的新階段。
通過新的互聯網連接設備獲取的數據可用于提高效率、實時決策、解決關鍵問題,并最終創造新的創新體驗。然而随着相互連接的設備越來越多,公司所面臨的碎片化和新挑戰也越來越多。為了獲取和利用數據的力量,他們需要解決方案來提供可互操作的端到端協作,從而在互聯網和設備之間架起橋梁,同時駕馭即将到來的創新浪潮。
SIMICAS® OEM 設備遠程運維套件是由 SIEMENS DE&DS DSM 團隊開發的一套面向設備制造商的數字化解決方案,該方案借助物聯網實現設備的高效遠程運維,對售後服務數據進行智能分析,從而真正實現整體售後環節的降本增效。
在 IIoT 大背景的發展浪潮下,SIMICAS 為企業提供了一個踏入數字化世界的靈活選擇,幫助企業根據自身發展需求定制數字化發展路徑。SIMICAS 解決方案由四個部分組成:SIMICAS 智能網關、SIMICAS 組态工具,以及兩個在西門子基于雲的開放式物聯網操作系統 MindSphere 基礎上開發的 APP——SIMICAS 生産透鏡和 SIMICAS 産效分析。
一、系統架構
在其 1.0 版中,我們使用了 Flink + Kafka + PostgreSQL + Redis 的架構。該系統的數據流如下:

設備數據通過部署至現場的網關上傳至物聯網接入組件,組件根據配置對數據進行解析處理後,将其寫入 Kafka 隊列,Flink 從 Kafka 中消費數據并進行計算,原始值及計算後的指标數據都會被寫入 PostgreSQL 中,值還會存一份到 Redis 中,以便更快地響應前端實時的數據查詢,設備曆史數據則從 PostgreSQL 中查詢。
二、業務挑戰
1.0 系統落地之後,我們遇到了兩大挑戰,一個是部署繁瑣,一個是應用複雜。
具體來說,因為引入了 Flink 和 Kafka,導緻系統部署時非常繁瑣,服務器開銷巨大;同時為了滿足大量數據的存儲問題,PostgreSQL 中不得不做分庫分表操作,應用程序較為複雜。
如何降低系統複雜度、減少硬件資源開銷,幫助客戶減少成本,成為研發團隊的核心任務。
三、技術選型
從産品的實際痛點出發,結合未來産品的發展規劃,我們團隊計劃對産品的數據處理部分進行重構,在技術選型時主要考慮了如下幾個方面:
· 高性能,可以支持百萬級别的并發寫入、萬級的并發讀取,大量聚合查詢時依然有高性能表現
· 高可用,可支持集群部署,可橫向擴展,不存在單點故障
· 低成本,數據庫對硬件資源要求低,數據壓縮率高
· 高度一體化,在具備以上三個特點的基礎上,是否具備一定的消息隊列、流式計算和緩存的功能
本着以上幾個需求,在對各種開源數據平台、時序數據庫(Time Series Database)進行選型對比後,我們發現 TDengine 正好符合産品重構所有的要求,尤其是低成本和高度一體化這兩個點,這是目前絕大部分數據平台或時序數據庫都不具備的,所以團隊果斷選擇了 TDengine。
四、落地實踐
數據流程
在确定選擇 TDengine 作為系統的序數據庫後,我們在 SIMICAS® OEM 2.0 版本中移除了Flink、Kafka 以及 Redis,新系統的數據流如下:
#FormatImgID_1#
數據建模
創建數據庫
數據默認保存 2 年,數據庫采用 3 節點集群,數據采用 3 副本存儲,保留能力;
1. create database if not exists simicas_data keep 712 replica 3 update 2;
創建實時數據表格
為平台中的每種設備類型創建一個獨立的超級表(super table),為每種設備類型下的每個具體設備創建獨立的設備子表。
1. create stable if not exists product_${productKey} (ts timestamp,linestate bool,${device_properties}) tags (device_code binary(64));
2. create table if not exists device_${device_code} using product_${productKey} tags (${device_code})
創建狀态表
為平台中所有設備創建一個共同的超級表。
1. create stable if not exists device_state (ts timestamp,linestate bool,run_status int,error_code binary(64),run_total_time int,stop_total_time int,error_total_time int) tags (device_code binary(64),product_key binary(64));
2. create table if not exists device_state_${device_code} using device_state tags (${device_code},${productKey})
指标計算
我們基于 JEXL 表達式 + 實時查詢的方式實現了系統中的指标計算。我們使用 JEXL 表達式來定義指标的計算表達式,系統解析後将變量替換成 SQL 查詢任務,在查詢返回結果後再到系統中進行計算,返回至前端。
比如計算某項目下所有設備當前電壓的平均值,其表達式為 avg(voltage,run_status=1 && project=abc),它會被分解為:1)查詢 run_status=1 && project=abc 的所有設備;2)查詢第一步結果中所有設備 voltage 字段的值;3)計算第二步所有設備結果的平均值。
得益于多線程和 TDengine 高效的查詢表現,單個 KPI 的查詢 P99 表現小于 100ms。
#FormatImgID_2#
五、遇到的問題
在 TDengine 官方推薦的實踐中,數據表建模建議使用多列模式,我們團隊在一開始選擇了這種方式,但是在實際使用中發現,部分客戶的設備測點非常多,甚至超過 2000 列,這樣可能會因為單行數據過大而導緻插入數據 SQL 過長的問題[1] ;另一個問題是現場設備是按照“OnChange(突發上送)”方式進行數據上傳,導緻非常多的 NULL 值出現,在執行last(*) from device_xxx 時效率較低[2]。

在與 TDengine 官方的技術人員溝通後,我們了解到,last 函數是對每列進行查找,直到最近一條非 NULL 值為止,在當時的版本下,cache 對 last 函數是無效的。
後來,團隊通過對項目中單個設備參數的數量進行限制,解決了問題[1];又通過修改設備數據的上傳方式,解決了問題[2]。
但是在根本上,還是我們在最初建模時,沒有充分考慮到客戶的業務場景,從而導緻了以上問題。因此,我們團隊後續在系統中實現了同時支持多列模式和單列模式,這樣客戶就可以根據現場的實際情況,自由切換建模方式。
六、寫在最後
與其他開源數據平台或數據庫相比,目前 TDengine 的運維監控能力還不算強大,不過前段時間發布的 TDinsight 已經帶來了很多改進,我們團隊也規劃在下一階段試用一下。
特别感謝濤思數據的陳偉燦及其他同事在産品開發過程給予的支持,雖然在過程中遇到一些問題,但整體而言,TDengine 的各項優異表現給了我們團隊很多驚喜。
最後期待 TDengine越來越好,幫助更多客戶、更多場景降本增效!
免責聲明:本文僅代表作者個人觀點,與每日科技網無關。其原創性以及文中陳述文字和内容未經本站證實,對本文以及其中全部或者部分内容、文字的真實性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,并請自行核實相關内容。
本網站有部分内容均轉載自其它媒體,轉載目的在于傳遞更多信息,并不代表本網贊同其觀點和對其真實性負責,若因作品内容、知識産權、版權和其他問題,請及時提供相關證明等材料并與我們聯系,本網站将在規定時間内給予删除等相關處理.

