开源纯C#工控网关+组态软件(七)数据采集与归档
?一、???引子
?在當前自動化、信息化、智能化的時代背景下,數據的作用日漸凸顯。而工業發展到如今,科技含量和自動化水平均顯著提高,但對數據的采集、利用才開始起步。
對工業企業而言,數據采集日益受到重視,主要應用場景包括:
節能降耗。投入(如車間的水電氣能耗、設備工時、原料耗用)和產出(產量、批數)這些成本核算的關鍵數據通過傳感器采集,取代人工抄表已成為趨勢。
績效考評。投入、產出、損耗、工時數據,其對管理者的決策支持、對員工的績效評估都很重要。
批次追溯。食品安全形勢日益嚴峻,對物料的追溯也成為國家硬指標。追溯就是追根溯源,批次生產的每個環節都需要數據跟蹤。
設備管理。如設備的運行時長對于設備保養、故障頻率對于設備維護、設備參數對于工藝優化。
數據既然如此重要,對于SCADA不但必須有,而且高要求:
準確性。信號不能失真,采集精度和時間戳盡可能精確;也不能帶入太多干擾和噪音。
完整性。信號不能頻繁丟失、丟步、跳步,萬一信號斷開,要快速重連,或者有冗余機制。
大容量。大數據,首先要能撐的起這個“大”。大項目動輒幾萬點,采集頻率又高,一天下來數據量都驚人,日積月累更是天量。例如對于 1萬點的系統, 1秒鐘存儲一次,每次單點占用 8字節,保存 10年的數據量將有 10000*8*10*365*86400=25228800000000字節,也就是 23TGB。若用 80GB硬盤存放,需 293塊硬盤。如此龐大的數據量,還要求快速插入、快速查詢。
要實現這些指標,非常具有挑戰性。
二、???實時庫與歷史庫
概述
工控環境特殊性在于,大量測點快速變化,需高速存取, IO密集型;數據結構簡單規則,無非就是名稱/ID、值、時間戳這些;數據流式存儲,只需在尾部插入,不刪不改。
因此常規的關系數據庫不僅存取速度跟不上,也顯得殺雞用牛刀。實時庫和歷史庫就是為工業環境準備的,測點的實時數據存儲在內存,保證最快的存取速度;數據超過一定范圍需要轉儲入歷史庫,我這里用了自定義格式的二進制文件,力求數據單元空間占用最小化、同時查詢速度最大化。
實時庫
測點數據在內存中,包含【下位機映射緩存:ICache】→【快照數據集:TagList】→【歷史數據緩存:HistoryList】這樣的三級結構。
ICache是下位機當前數據的緩存,隨掃描過程實時更新,繼承IReaderWriter接口,可讀可寫,可以通過Tag的Read\Write讀取和更新。
對當前所有測點數據的快照查詢,可以通過Tag的清單列表MetaTagList結合神器Linq實現。Linq對內存列表數據的查詢能力可以說既強大又優雅,這是微軟送給C#碼農的禮物,不再贅述。
測點數據改變就會生成一條新的記錄。這些記錄如馬上轉儲到數據庫或文件,則測點數量多變化快,其IO是系統不能承擔之重。但如果測點記錄堆積過多不及時清理,則一方面可靠性下降,如系統崩潰、斷電就會發生大量數據點丟失,同時內存占用越來越大,影響系統性能。所以測點歷史數據的緩存容量應可根據測點數量和存取頻率自適應或由用戶自定義。
歷史庫
海量的測點數據,普通關系數據庫是難以招架的。如SQL SERVER免費版只有4-10個G上限。而這個容量可能一個月就溢出了。
因此,為了適應天量數據,就需要二進制文件存儲。有人會問為啥不用NO SQL,Hadoop這些高大上的東東,我的觀點是不追求高大上,因為工控數據不同于搜索引擎,都是簡單而標準的結構。可以根據其特點進行有針對性的設計,無需部署復雜的NO SQL架構也一樣可以實現高性能。
歷史數據庫要最大限度的壓縮數據,同時又要保證快速插入、快速查詢。
如何保證數據單元最小化?
分析存儲結構,一條記錄包括變量名、當前值、時間戳。
變量名可能為一個長字符串,數據量大之后顯然是過于冗長。因此代之以ID號(2字節)。還可以進一步壓縮,如相同變量存在一起,ID也可以省了。
當前值大部分是浮點數,4字節,這個不能縮減,否則影響數據精度。
時間戳為DateTime,要占8字節,但如果數據按日排序,日期部分省去,4個字節的時間部分就可以精確到毫秒。
這樣,通過合理設計存儲結構,一條記錄可以壓縮到8個字節(開關量5個字節)。
如何保證快速插入記錄?
存檔文件日積月累肯定是越來越龐大,如果采用覆蓋式寫入或更新寫入,不僅可靠性下降,讀寫成本也越來越高。想快速插入必須保證每次寫入不改變原來的數據,僅僅在末尾追加。
如何保證快速查詢?
首先為保證可靠性和數據容量限制,數據分月存放。文件名為【年-月.bin】。如需跨月查詢,按文件名搜索拼接即可。開頭256個字節存放日期索引。32*8字節,對應每日記錄的頭指針,也即上一日記錄的末尾。
主索引下,每一天的記錄頭為日內索引區。包含一個索引數組,每一項索引有變量ID、變量長度、數量。如要查某日某ID的變量,即可先找到ID,再根據其變量長度*數量累加計算,即可定位到該變量的第一條記錄。
同一變量的記錄按時間戳順序排列。這樣,要定位到該變量某一時間的記錄,即可對時間戳采用二分法快速定位。
字符串類型的歸檔比較特殊,專門在EventLog作為日志存取。
三、???數據轉儲流程
為什么要建立三級轉儲
數據在什么情況下會被采集?默認是變化了采集。如果一個數據長期不變,但需要定期采樣,可以設置歸檔周期:
?
數據被采集之后首先是存在內存中。內存的特點是快,小。存取快,但是容量有限,采樣數據堆積多了就要清理轉儲到關系數據庫。
為什么要多一層關系數據庫?因為采樣的數據是時間序列的,但最終二進制文件的索引結構按照變量-時間戳排布,比如依次排入變量A-13:40,變量B-13:41,變量A-13:42這樣一個時間序列,如直接寫二進制存檔文件就需按變量排序并重新整理寫入,文件越大其寫入效率越低,對系統拖累越大。而先轉儲到關系數據庫,再定期將上一日的數據轉儲到二進制文件,既可以充分利用關系數據庫的高性能批量插入功能(在SQL SERVER就是Sqlbulkcopy),又可利用關系庫的查詢排序能力,一舉兩得,轉儲之后數據庫記錄清空,也避免關系庫容量溢出的問題。
由上所述,轉儲包含【歷史數據緩存:HistoryList】→【關系數據庫:Log_HDA】→【二進制文件:bin文件】三級。
每轉儲成功一次,上一級的數據就清空,保證每一級之間的數據不重疊。
這樣一來,數據記錄就分布于三個位置:內存、關系庫、二進制文件。要查詢數據,就需要對這三部分數據進行“拼接”。拼接的規則就是以當前級最末一條記錄的時間戳為準。如當前級中沒有,就查下一級。
源頭:內存數據庫
內存數據庫是一個HistoryData列表。有兩種情況可以觸發清理:定期清理、溢出清理。定期清理是設置固定的周期。溢出就是超過一定大小,到時間就轉到關系庫。可由server.xml配置。
中介:關系數據庫
就是數據庫的Log_HDA表。承上(內存)啟下(二進制文件),暫存數據。也包含ID、值、時間戳這幾個字段。每天凌晨開始,網關服務調用DataHelper內部的WriteToFile方法(實際是調用關系庫的WRITEHDATA存儲過程),對暫存的測點記錄按時間、變量排序,轉儲到二進制文件中。如寫入失敗,判斷最后一個時間戳,下一次繼續追加寫入,類似斷點續傳。
存儲:二進制數據庫
二進制存檔文件按月存放,自帶索引。所有對其操作均在DataHelper的HDAIOHelper?類中。包括從數據庫寫入、查詢、定期轉儲、壓縮歸檔(用旋轉門算法)等。為提高讀寫性能,采用內存映射文件MemoryMappedFile。
四、???應用場景
數據應用場景
數據的應用場景,主要是查詢、顯示、挖掘。查詢→生成各種報表、圖表,以供人工分析比較;顯示→圖形化展示,一目了然;挖掘→結合先進的挖掘工具,找出數據內在關聯性,提供決策支持。
?
數據查詢
目前支持的查詢場景包括:按時間段檢索、按變量ID檢索、獲取某變量在一段時間內的平均值/最大值/最小值/初始值/當前值。如要對一段記錄執行復雜查詢(如按時間間隔分組等),需要取出該時間段內所有記錄,用Linq查詢。
數據顯示
目前支持實時數據顯示和歷史數據趨勢圖。我這里用了一套微軟俄羅斯研究院的DynamicDataDisplay開源組件,性能不錯,很適合動態圖顯示,目前還發展出了javascript版本。
?
數據報表
利用微軟的RDLC報表和Chart圖表的強大功能,可以方便的設計出各種復雜報表、圖表。順帶贊一下RDLC,集成于Visual Studio和SQL SERVER,可以在Web顯示,支持內嵌表格、儀表、圖表、鉆取報表,還可以方便的導出為Excel、Pdf、Word,與.NET 完美集成,強烈推薦。
未來改進
分布式:對一個大系統,分布式是必須的。即數據分別在不同節點采集、存儲,但形式上依然是一個整體,可以統一查詢和傳輸。
內存映像:目前的測點緩存模式存在可靠性不足的問題(如突然斷電或系統崩潰造成的數據丟失),可依賴Sqlite和內存映像解決。
MQTT:物聯網通行的MQTT協議可以解決不同系統之間的實時訂閱傳輸問題。
查詢擴展:原生支持按時間間隔分組取出數據等常用查詢場景,可以有效提高查詢性能。
安全控制:采用證書認證方式,加強權限管理,防止數據傳輸過程中被篡改。
數據歸檔流程:
五、???下面的計劃
網關層接口概述
上下位機通訊原理
如何實現一個設備驅動
如何設計圖元
數據采集與歸檔
VS插件模塊及原理
歸檔模塊及文件格式
如何進行功能擴展
組態變量表達式實現
github地址:https://github.com/GavinYellow/SharpSCADA。QQ群:102486275
相關文章:?
.NET十年回顧
開源純C#工控網關+組態軟件
開源純C#工控網關+組態軟件(三)加入一個新驅動:西門子S7
開源純C#工控網關+組態軟件(四)上下位機通訊原理
開源純C#工控網關+組態軟件(五)從網關到人機界面
開源純C#工控網關+組態軟件(六)圖元組件
原文:http://www.cnblogs.com/evilcat/p/7909578.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的开源纯C#工控网关+组态软件(七)数据采集与归档的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深港澳大湾区第三次.NET技术交流会圆满
- 下一篇: 使用Api分析器与Windows兼容包来