王燦達,李 悅,李 鋒
(東華大學 計算機科學與技術學院,上海201620)
伴隨著《中國制造2025》戰略計劃的不斷推進,學術界與工業界將越來越多的目光投向了智能制造的研究與實踐。為了生產數據實時處理的需要,數據在邊緣側處理后,再與云計算中心進行交互,這種云邊協同的模式是智能制造發展的一個新趨勢[1]。保證生產信息的收集、存儲與傳輸,使得云中心能快速方便地獲取到來自于生產設備的信息,是實現云邊協同的關鍵因素。但目前生產設備種類繁多,通訊接口協議各異,上層應用系統需針對各類設備單獨開發子模塊用于數據交互,這無疑增大了開發的難度,阻礙了智能制造的發展[2]。OPC統一架構即OPCUA,定義了一組高可用、高性能和跨平臺的數據交互規范[3]。基于OPCUA技術所開發的網關可屏蔽不同設備的通訊細節,對外部系統訪問生產設備數據提供統一標準的接口[4]。在實際生產中,網關處于生產設備邊緣,由于現場網絡的不確定性較高,通訊不穩定,存在數據丟失的風險。而在工業生產中,網關所傳輸的數據涉及到設備主要生產指標以及控制數據,對數據的完整性要求較高。因此,OPCUA網關中應具備數據存儲能力,遇到網絡中斷時,網關可繼續準確采集,并將數據存儲到非易失設備中,當網絡恢復正常時,其它第三方平臺可從網關中獲取完整數據。這就保證了可靠的數據服務,提高了系統的魯棒性與容錯性[5]。
目前,在智能制造網關的研究中,學者大多關注于不同協議之間的轉換[6]、信息通訊的安全性[7]以及網關的邊緣計算能力[8]等方面,部分學者注意到了網關對于數據的存儲能力,但現有的數據庫系統仍是其不二選擇。文獻[9]在對基于OPCUA的工控信息化數據網關的研究中采用了SQLite;文獻[10]在設計家庭看護系統的智能網關時選擇了MongoDB。此外MySQL、HBase也廣受學者們的青睞[11]。由于數據庫的運行需要較多的系統資源,這就對硬件配置提出了較高的要求,而網關設備硬件資源緊張,運行數據庫軟件較為困難。此外,操作數據庫需要建立網絡連接、傳輸數據、關閉連接等一系列耗時步驟,這會導致網絡I/O速度成為系統運行效率的瓶頸。現有的數據庫軟件為追求更廣泛的應用場景,其存儲與查詢設計具有一定的通用性,并不會針對OPCUA網關程序做專門的優化。基于上述現狀,本文設計了一套內存與外存協同的數據存儲系統(Storage System Based On Ram And External Storage Data,簡稱RES),專用于對OPCUA網關數據的存儲。RES只保留了核心的數據存儲與查詢功能,抹除了事務、存儲過程等額外的數據庫功能,故其資源占用率小,硬件要求低;另外RES可直接嵌入到OPCUA應用程序中,二者之間的互操作不再需要占用網絡I/O資源,大幅度提升了程序運行效率。
OPCUA網關采集設備信息并存儲,對外部呈現OPCUA數據接口。在邏輯上,網關系統分為3層,分別為采集層、存儲層與服務層,如圖1所示。采集層讀取生產設備數據,整合目前采集生產數據常用的接口(如RS485、RS232、USB等),并針對不同的通訊方式開發不同的驅動程序完成數據的采集,之后將數據寫入到存儲層。存儲層為服務層提供數據支撐,分為內存存儲與外存存儲兩部分。外部系統通過OPCUA客戶端與網關服務層建立安全連接。連接成功的客戶端可瀏覽服務層地址空間,訪問結點的當前數據與歷史數據,還可以對節點進行訂閱,當數據更新時自動獲取。

圖1 網關整體架構Fig.1 Gateway architecture
數據庫可劃分為二種,一種是傳統的關系數據庫,主要以外存作為存儲介質,如Oracle、MySQL等,數據的訪問會同時涉及磁盤I/O與網絡I/O,速度較慢;另一種是實時數據庫,主要以內存作為存儲介質,如Redis、Memcached等,此類數據庫直接基于內存操作,速度較快,但受限于內存資源,其存儲容量有限。若將二者結合,外存型數據庫用于持久化存儲“冷數據”,即訪問頻次較低的數據;內存型數據庫緩存“熱數據”,即訪問頻次較高的數據,可揚長避短提升系統性能。本文的RES就是基于上述思想所設計,用以適應OPCUA網關中采樣數據管理,在有限的硬件資源下可保證數據的讀寫速率與存儲容量。
生產過程中設備數據具有數值和時間屬性,本文采用OPCUA標準中的DataValue數據對象來表示。DataValue的各屬性見表1。

表1 DataValue屬性Tab.1 Datavalue property
DataValue對象可描述某個節點在某一時刻的具體值,對其按照時間順序存儲,則可記錄某一節點數據隨時間的變化情況。由于數組可滿足對元素的有序存儲,故本文為每個節點建立一個固定長度的DataValue數組,在內存中存儲該節點的時序數據。為建立起節點與數組的對應關系,方便根據節點的唯一標識符(nodeId)對數組進行查找,本文引入哈希集合作為最外層容器。哈希集合以鍵值對的方式進行數據映射與存儲,每個節點的nodeId作為鍵,與節點對應的數組作為值共同存儲在哈希集合之中。內存存儲結構如圖2所示。

圖2 內存存儲結構Fig.2 RAM storage structure
外存存儲結構三要素為:記錄、數據頁、索引,如圖3所示。記錄是節點數據在外存中最基本的存儲形式,每行記錄包含3個字段見表2,分別是nodeNumber、value、timeStamp。為方便對記錄排序,本文對OPCUA模型中所有節點重新編號并與其nodeId一一對應。

圖3 外存存儲結構Fig.3 External storage structure

表2 記錄字段Tab.2 Record field
數據頁保存著記錄,可分為3部分:頭信息、頁目錄與記錄。頭信息是為生成索引服務的,包含數據頁所有記錄中最早時間的時間戳與最晚時間的時間戳;每個節點所對應的記錄在此數據頁的位置區間存放于頁目錄之中,通過查閱頁目錄可高效地根據節點編號鎖定想要的數據。為方便對數據頁的組織管理,數據頁大小固定且以阿拉伯數字順序從1開始逐個編號,越晚生成的數據頁其頁號越大。索引頁只記錄數據頁頁號及此數據頁的頭信息,在查詢所需數據時遍歷索引,可快速定位目標數據頁。
2.3.1 數據寫入機制
設備數據從網關采集層寫入網關存儲層的流程如圖4所示。首先會在OPCUA地址空間中更新此節點的當前值,之后根據此值封裝一個DataValue對象放入與該節點對應的數組,用于在內存中緩存節點的“熱數據”。若數據量超出了數組的容量,則會按照時間順序對早期放入數組的數據進行清除,確保內存中總是緩存設備新產生的數據,在實際生產中新數據被訪問的頻次大于舊數據。

圖4 數據寫入流程Fig.4 Data writing process
為確保節點數據的完整性以及整個系統的魯棒性,當數據更新時還會生成一條記錄,用于在外存中持久化存儲。考慮到外存I/O耗時較長,此記錄并不會立即同步至外存,而是先放入位于內存的記錄暫存區,等待時機批量寫入,以減少I/O次數,從而提升系統性能。記錄由暫存區寫入外存的條件:一是每隔固定的時間間隔進行一次數據同步,二是暫存區數據量達到規定數目,滿足任意一個即可。
記錄從暫存區寫入外存過程如下:
(1)獲取待寫入數據的數據頁。計算最晚生成的即頁號最大的數據頁的長度,若超過規定的長度則創建新的數據頁,否則直接寫入到此數據頁中。
(2)更新數據頁的頭信息。取暫存區中最晚記錄的時間戳來更新頭信息的最晚時間。若頭信息中已有最早時間則無需更新,否則取暫存區最早記錄的時間戳來設定頭信息的最早時間。
(3)記錄排序。將暫存區的記錄與數據頁中原有的記錄混合,并按照編號與時間戳這2個字段進行升序排列。
(4)更新數據頁的頁目錄。遍歷排序后的記錄值,得出每個節點所對應的記錄的位置區間,最后生成新的頁目錄。
(5)將頭信息、頁目錄、有序記錄寫入數據頁,并在索引中更新此數據頁的頭信息。
(6)清空記錄暫存區。
2.3.2 數據訪問機制
各類外部系統通過網關服務層對數據進行訪問分為兩種情況:一是對于節點當前值的讀取,這種方式比較簡單直接依據OPCUA規范返回對應數據即可;另一種是對于節點在某段時間范圍內歷史數據的讀取,此時需要查詢RES以獲取數據。3個關鍵查詢信息分別為nodeId、開始時間、結束時間。詳細步驟如下,流程如圖5所示。

圖5 數據讀取流程Fig.5 Data reading process
(1)根據nodeId在哈希集合中查找到存放DataValue對象的數組。
(2)遍歷數組,若滿足查詢條件則返回對應數據,若不滿足則查找位于外存的記錄。
(3)根據開始時間與結束時間遍歷索引,得到滿足條件的若干個數據頁。
(4)逐一處理數據頁,由nodeId所對應的編號去查詢頁目錄定位并獲取數據。
(5)把此次在外存中查找到的數據放入內存對應的數組中。即“冷數據”升級為“熱數據”,提升下次查詢的速率。
(6)將在內存與外存中查找到的數據一并返回給客戶端。
本文以染整車間中定型機為基礎搭建OPCUA網關,以對RES進行測試。定型機包含多個監控單元,每個監控單元監控某項指標。如,烘房溫度、布面含潮率,同時也對應著OPCUA地址空間中的一個節點。網關采集層通過RS485接口從定型機的監控單元獲取數據存入RES,網關服務層接收OPCUA客戶端的請求并返回相應數據。
網關的硬件平臺基于Raspberry Pi 3B,其CPU配置為64位1.2 GHz四核心,內存1 G、外存32 G。本文選取了以外存為存儲介質的關系型數據庫MySQL和以內存為存儲介質的鍵值對數據庫Redis作為RES的比較對象,來評測RES的各項性能指標。在MySQL中建立數據表存儲節點數據,具體字段信息見表3。為提升數據查詢的速率,在該表中以update_time與node_id字段建立了索引。

表3 MySQL數據表信息Tab.3 MySQL data table information
節點數據在Redis中以hash表的方式進行存儲,每一個OPCUA節點對應于Redis中的一個hash表,即Redis中的每一個hash表都以OPCUA節點的nodeId當做鍵值。在hash表中該節點數據以更新時刻的時間戳作為字段名稱,這一時刻節點的值當做與該字段對應的值,具體存儲結構如圖6所示。

圖6 Redis存儲結構Fig.6 Redis storage structure
為測試不同存儲方案下數據的寫入速率,本文隨機模擬定型機在運行時所產生的數據,以連續寫入1 000條數據為起始,步長為1 000,遞增到10 000條。每個量級寫入5次,并計算出平均寫入時間,具體結果如圖7所示。MySQL寫入數據所用時間最多,且隨著數據量的增大,所用時間的增幅也非常明顯;Redis與RES寫入速度較MySQL有明顯的提升,數據量增大時,所用時間的增幅趨于平緩;Redis的寫入速率略高于RES。在寫入時MySQL、Redis、RES這3種方案CPU的平均使用率為38%,32%,29%;內存平均使用率為35%,28%,27%。

圖7 不同方案寫入數據所用時間Fig.7 Data writing time of different schemes
對于數據讀取速度的測試,本文首先在MySQL、Redis、RES中分別存入10 000條記錄,并隨機讀取某個節點在某個時間段內的歷史數據。統計讀取100次,以100為步長遞增到1 000次不同方案所用的時間,具體結果如圖8所示。MySQL對于SQL語句有著很好的支持,一條簡單的SQL語句即可完成查詢,雖操作方便但速度并不理想;Redis對于數據的操作方式較少,且其內部并不會對數據按照時間排序,故只能采用遍歷的方式篩選出合格的記錄;RES在寫入時對數據建立了索引與頁目錄,并且數據全部按照時間順序排列,使其在查詢時無需遍歷,可以直接查找到所需記錄,大幅度提升了查詢效率。在查詢時MySQL、Redis、RES這3種方案CPU的平均使用率為30%,29%,28%;內存平均使用率為38%,45%,29%。

圖8 不同方案查詢數據所用時間Fig.8 Data query time of different schemes
在實際工業生產中數據量巨大,在千萬級別的數據量下RES仍有較好的表現。寫入性能方面,MySQL與RES寫入10 000 000條數據分別用時約30.91 h、2.24 h。由于網關硬件資源有限,內存只有1 GB,當Redis的數據寫入量達到60 000 000左右時,則已達到其容量瓶頸不能繼續操作。數據查詢方面,基于千萬級數據量隨機查詢100次MySQL、RES所用時間分別為9 282.89 s、1 722.16 s。
本文對網關中的數據存儲進行了研究,設計并實現了內存與外存協同的數據存儲系統,內存做數據緩存,外存做持久化存儲,兼顧了數據存儲容量與操作效率,在計算資源限的開發板上,相比傳統的數據庫MySQL與Redis有更好的性能表現。OPCUA網關解決了不同生產設備之間、生產設備與外部系統之間難以互聯互通的問題,對于OPCUA網關的進一步發展具有一定的參考意義。