李 鋼,茅海泉
(南瑞集團(tuán)有限公司(國網(wǎng)電力科學(xué)研究院有限公司),南京 211000)
(江蘇瑞中數(shù)據(jù)股份有限公司,南京 210012)
在電網(wǎng)系統(tǒng)中產(chǎn)生的準(zhǔn)實(shí)時(shí)數(shù)據(jù)[1],可以被應(yīng)用在調(diào)度、在線監(jiān)測、計(jì)量等多種場景中.海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺(以下簡稱海量平臺)是南方電網(wǎng)公司面向數(shù)據(jù)資源統(tǒng)一管理及針對實(shí)時(shí)數(shù)據(jù)管理的有力支撐平臺,可以對生產(chǎn)運(yùn)行過程中各業(yè)務(wù)應(yīng)用形成的實(shí)時(shí)歷史數(shù)據(jù)進(jìn)行存儲、集中、整合、共享和分析,同時(shí)提供了標(biāo)準(zhǔn)統(tǒng)一的NOSQL訪問方式.
隨著電網(wǎng)規(guī)模的不斷擴(kuò)大、信息系統(tǒng)的不斷升級擴(kuò)展,準(zhǔn)實(shí)時(shí)數(shù)據(jù)呈現(xiàn)海量的特點(diǎn),具有明顯的大數(shù)據(jù)[2]特征.Spark[3]、HBase[4]等大數(shù)據(jù)服務(wù)平臺是目前流行的大數(shù)據(jù)解決方案,得到廣泛的應(yīng)用.大數(shù)據(jù)服務(wù)平臺可以運(yùn)用到電網(wǎng)系統(tǒng)中,更好的解決海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)的存儲、計(jì)算、分析等問題,具有很高的實(shí)用價(jià)值.大數(shù)據(jù)平臺可以通過JDBC與外部數(shù)據(jù)源進(jìn)行連接,獲取電網(wǎng)檔案、模型等關(guān)系數(shù)據(jù).而海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺提供統(tǒng)一訪問接口UAPI不支持SQL查詢.如何將海量平臺中非結(jié)構(gòu)化的量測數(shù)據(jù)與模型、檔案等關(guān)系數(shù)據(jù)通過統(tǒng)一SQL訪問引擎結(jié)合起來,成為運(yùn)用大數(shù)據(jù)服務(wù)平臺的關(guān)鍵問題.
本文采用分層的策略,在上層大數(shù)據(jù)平臺與底層海量平臺間設(shè)計(jì)實(shí)現(xiàn)專門的SQL引擎.大數(shù)據(jù)平臺通過該引擎,運(yùn)用SQL的方式訪問海量平臺中的數(shù)據(jù).SQL引擎基于PostgreSQL設(shè)計(jì)實(shí)現(xiàn),能解析大數(shù)據(jù)層的SQL語句并通過UAPI獲取海量平臺數(shù)據(jù).現(xiàn)場測試結(jié)果驗(yàn)證了該接口的有效性.
海量平臺中,非結(jié)構(gòu)化數(shù)據(jù)主要存儲在實(shí)時(shí)數(shù)據(jù)庫中.目前國產(chǎn)的實(shí)時(shí)數(shù)據(jù)庫僅支持簡單的SQL查詢,無法支持復(fù)雜SQL的查詢,如與結(jié)構(gòu)化數(shù)據(jù)結(jié)合的嵌套查詢或者join查詢等.因此,需要開發(fā)專用的SQL引擎來實(shí)現(xiàn)結(jié)構(gòu)化數(shù)據(jù)與非結(jié)構(gòu)化數(shù)據(jù)的聯(lián)合查詢,為大數(shù)據(jù)應(yīng)用提供數(shù)據(jù).基于PostgreSQL的SQL引擎是一種很有效的解決方案.
PostgreSQL是由加州大學(xué)伯克利分校[5,6]開發(fā)的開源數(shù)據(jù)庫系統(tǒng),可以運(yùn)行在Windows、Linux等多種平臺上.PostgreSQL是世界頂級關(guān)系數(shù)據(jù)庫之一,被廣泛運(yùn)用在醫(yī)療、天文、商業(yè)等領(lǐng)域[7].PostgreSQL的主要技術(shù)特點(diǎn)包括:
1)標(biāo)準(zhǔn)通用.PostgreSQL基于廣泛應(yīng)用的關(guān)系數(shù)據(jù)模型,遵循SQL國際標(biāo)準(zhǔn).PostgreSQL為應(yīng)用開發(fā)提供了符合標(biāo)準(zhǔn)的 ODBC3.0、JDBC3.0、OLEDB 2.7和嵌入式 SQL 接口.PostgreSQL經(jīng)過大量實(shí)際應(yīng)用的磨合與驗(yàn)證,已成為標(biāo)準(zhǔn)、通用、安全、穩(wěn)定、實(shí)用、高效的數(shù)據(jù)存儲與管理平臺.
2)海量存儲.PostgreSQL結(jié)合結(jié)構(gòu)化查詢語言的操作能力和過程化語言的數(shù)據(jù)處理能力,可以有效地支持大規(guī)模數(shù)據(jù)存儲與存取,如TB級的數(shù)據(jù)庫的表空間、GB級的 BLOB 二進(jìn)制大對象和 CLOB 文本大對象等,并通過各種約束保證數(shù)據(jù)的完整性和安全性.
3)Postgres_fdw.Postgres_fdw為PostgreSQL數(shù)據(jù)庫的外部數(shù)據(jù)封裝器,可以用來訪問存儲在數(shù)據(jù)庫外的數(shù)據(jù).Postgres_fdw支持支持標(biāo)準(zhǔn)的SQL select語句,不支持insert,update等語句,通過Postgres_fdw,可采用統(tǒng)一的SQL訪問不同數(shù)據(jù)源的數(shù)據(jù).
4)訪問高效.PostgreSQL采用c語言編寫,運(yùn)用多進(jìn)程模型,支持高并發(fā)訪問.將結(jié)果存儲在內(nèi)存中,有效避開無用的磁盤讀寫,具有高效訪問的特點(diǎn).
基于以上技術(shù)優(yōu)勢,本文采用PostgreSQL來設(shè)計(jì)統(tǒng)一SQL引擎.
統(tǒng)一訪問接口(UAPI)是海量平臺對外提供的一套實(shí)時(shí)數(shù)據(jù)訪問接口,UAPI不支持SQL訪問.UAPI屏蔽了底層數(shù)據(jù)庫的具體實(shí)現(xiàn)細(xì)節(jié)及差異,對外提供統(tǒng)一的訪問接口為上層應(yīng)用服務(wù),對用戶來說是只有一個(gè)邏輯實(shí)時(shí)數(shù)據(jù)庫,從而實(shí)現(xiàn)了透明性以及分布式訪問.
實(shí)時(shí)數(shù)據(jù)庫統(tǒng)一訪問接口的實(shí)現(xiàn)以標(biāo)準(zhǔn)C/C++語言為編程語言并充分考慮接口的跨平臺性,接口至少支持Windows、Linux等平臺.
在電網(wǎng)系統(tǒng)中運(yùn)用大數(shù)據(jù)存儲、分析工具,需要實(shí)現(xiàn)將底層海量平臺的數(shù)據(jù)導(dǎo)入到大數(shù)據(jù)平臺.大數(shù)據(jù)平臺通過JDBC接口連接外部數(shù)據(jù)源,而海量平臺已實(shí)現(xiàn)UAPI供外部調(diào)用.本文設(shè)計(jì)實(shí)現(xiàn)了基于PostgreSQL的SQL引擎,實(shí)現(xiàn)在大數(shù)據(jù)端通過SQL的方式訪問、抽取海量平臺實(shí)時(shí)數(shù)據(jù).本文訪問引擎實(shí)現(xiàn)的主要功能包括:
不包括where條件的查詢.用于查詢所有測點(diǎn)的信息.
帶where條件的測點(diǎn)查詢.查詢符合特定條件的測點(diǎn)信息.此處的條件包括測點(diǎn)標(biāo)識和測點(diǎn)名.
原始值、斷面、實(shí)時(shí)值、差值[8]查詢.查詢測點(diǎn)不同類型的值信息.
模糊查詢.便于查詢符合特定條件的相關(guān)測點(diǎn)集信息.
帶子查詢的where條件查詢.可以在查詢語句中嵌套子查詢,方便更深層次的應(yīng)用需求.
指定字段的查詢.用于查詢測點(diǎn)的部分信息.
大數(shù)據(jù)平臺與海量平臺間通過本文的訪問插件進(jìn)行連接.具體架構(gòu)如圖1所示.
圖1 整體架構(gòu)圖
如圖1,整體架構(gòu)分為三層,分別是:
接口層: 接口層是大數(shù)據(jù)平臺的管理接口,主要部署SparkSQL[9].SparkSQL支持在Java,Scala,Python和R等高級語言中使用標(biāo)準(zhǔn)的SQL語句在Spark中查詢結(jié)構(gòu)化數(shù)據(jù).大數(shù)據(jù)分析應(yīng)用調(diào)用SparkSQL接口實(shí)現(xiàn)對海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺的數(shù)據(jù)查詢和分析計(jì)算.
大數(shù)據(jù)平臺層: 大數(shù)據(jù)平臺是電網(wǎng)系統(tǒng)中大數(shù)據(jù)工具的部署層,主要涵蓋Spark、HDFS[10]和HBase.Spark負(fù)責(zé)準(zhǔn)實(shí)時(shí)數(shù)據(jù)的計(jì)算分析,HDFS和HBase解決實(shí)時(shí)歷史數(shù)據(jù)的存儲問題.
海量平臺層: 海量平臺層是目前電網(wǎng)系統(tǒng)中部署的實(shí)時(shí)數(shù)據(jù)管理平臺,負(fù)責(zé)對關(guān)系數(shù)據(jù)庫、實(shí)時(shí)數(shù)據(jù)庫等數(shù)據(jù)源的統(tǒng)一管理.在底層的數(shù)據(jù)源上是本文重點(diǎn)設(shè)計(jì)實(shí)現(xiàn)的SQL解析引擎.大數(shù)據(jù)訪問接口通過JDBC與大數(shù)據(jù)平臺連接,與底層的海量平臺通過UAPI連接.整體上,海量平臺作為大數(shù)據(jù)平臺的外部數(shù)據(jù)源,通過本文的訪問插件為上層提供數(shù)據(jù)支撐.
本文基于PostgreSQL的FDW(Foreign Data Wrapper)框架,設(shè)計(jì)海量平臺大數(shù)據(jù)訪問接口.本接口對外支持標(biāo)準(zhǔn)JDBC訪問方式.海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺大數(shù)據(jù)接口模塊架構(gòu)圖如圖2.
圖2 海量平臺大數(shù)據(jù)接口模塊架構(gòu)圖
海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺大數(shù)據(jù)接口模塊由三部分組成:
1)標(biāo)準(zhǔn)JDBC接口: 基于PostgreSQL對外提供的JDBC接口.用于與上層的Spark、HBase等連接.
2)PostgreSQL插件: 把PostgreSQL數(shù)據(jù)庫作為海量平臺大數(shù)據(jù)接口的一個(gè)功能插件.此處主要利用PostgreSQL的外部表訪問功能以及PostgreSQL對SQL語句的初步處理.
3)海量平臺FDW模塊: 基于PostgreSQL的FDW模塊,實(shí)現(xiàn)對海量平臺外部數(shù)據(jù)源的訪問.
整個(gè)大數(shù)據(jù)接口模塊中FDW模塊是本文的核心.FDW模塊位于接口的底層,負(fù)責(zé)連接PostgreSQL與海量平臺.FDW模塊將系統(tǒng)上層大數(shù)據(jù)部分傳入的SQL語句具體解析后調(diào)用相關(guān)的UAPI函數(shù)以實(shí)現(xiàn)準(zhǔn)實(shí)時(shí)數(shù)據(jù)的傳輸.
海量平臺SQL引擎位于海量平臺大數(shù)據(jù)接口的底層,基于PostgreSQL的FDW模塊設(shè)計(jì)實(shí)現(xiàn).整體的設(shè)計(jì)思路是將海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺中的數(shù)據(jù)抽象成PostgreSQL的外部表以支持訪問.
電網(wǎng)應(yīng)用中的準(zhǔn)實(shí)時(shí)數(shù)據(jù)主要包括測點(diǎn)信息和測點(diǎn)值信息,海量平臺FDW模塊相應(yīng)的映射為PostgreSQL的外部點(diǎn)表(upoint)和外部值表(uvalue).外部表的字段與實(shí)時(shí)數(shù)據(jù)中包含的信息相對應(yīng),例如外部值表中包含了測點(diǎn)標(biāo)識、時(shí)間戳、質(zhì)量位、值等字段.
基于上述思路,設(shè)計(jì)海量平臺FDW模塊的流程圖,如圖3所示.
海量平臺FDW模塊的主要實(shí)現(xiàn)流程包括:
連接海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺.與海量平臺建立連接是進(jìn)行數(shù)據(jù)傳輸?shù)牡谝徊?
圖3 海量平臺FDW模塊實(shí)現(xiàn)流程圖
估算外部表大小.估算映射的外部表的大小,為后面查詢做準(zhǔn)備.
創(chuàng)建外部表查詢訪問路徑和掃描計(jì)劃節(jié)點(diǎn).根據(jù)外部調(diào)用的IP地址是否是本地,設(shè)置不同的權(quán)重參數(shù);創(chuàng)建訪問路徑.
查詢初始化.主要是解析SQL語句.PostgreSQL對SQL語句進(jìn)行了簡單的分詞處理,在FDW模塊中還需進(jìn)一步分析SQL的語義信息,特別是SQL語句中where條件的處理.
執(zhí)行查詢并返回結(jié)果集.根據(jù)解析的SQL語句,調(diào)用對應(yīng)的UAPI函數(shù),將結(jié)果集組織成PostgreSQL中的記錄格式返回.
海量平臺SQL引擎的各功能點(diǎn)協(xié)調(diào)有序處理,能保證上層的SQL查詢正確解析;在映射成外部表的基礎(chǔ)上,調(diào)用相關(guān)UAPI函數(shù),順利完成訪問任務(wù).
在查詢外部表獲得具體的字段信息前,需要對外部表進(jìn)行大小估算,以生成更優(yōu)的訪問路徑.本文中外部表包括外部點(diǎn)表和外部值表,分別設(shè)計(jì)了不同的大小估算方案.
外部點(diǎn)表大小估算: 首先查詢出總共的點(diǎn)數(shù),然后乘以每個(gè)點(diǎn)結(jié)構(gòu)所占的大小即可得整體點(diǎn)表的大小.
外部值表大小估算方案較復(fù)雜,具體流程如圖4所示.
外部值表大小估算: 如圖4,在海量平臺中,每個(gè)測點(diǎn)包含的值的個(gè)數(shù)不等,不能簡單的根據(jù)單個(gè)測點(diǎn)值的個(gè)數(shù)乘以測點(diǎn)總數(shù)來估算.而海量平臺中測點(diǎn)數(shù)在千萬級別,采用逐個(gè)測點(diǎn)查詢累加的方式會嚴(yán)重?fù)p害效率.本文采用隨機(jī)抽樣的方式,抽取總點(diǎn)數(shù)的二十分之一,計(jì)算此部分的測點(diǎn)值總個(gè)數(shù),最后乘以比例得到整體的估計(jì)值.
圖4 外部值表大小估算方案示意圖
SQL語句解析是查詢過程中的重要一環(huán).海量平臺FDW模塊在PostgreSQL詞法分析的基礎(chǔ)上,結(jié)合本系統(tǒng)的查詢要求,進(jìn)行SQL語句的補(bǔ)充改造與語義解析,方便查詢時(shí)對應(yīng)到具體的UAPI函數(shù).SQL語句解析的整體框架如圖5所示.
圖5 SQL語句解析框架圖
SQL語句解析主要包括以下解析過程:
根據(jù)select后的字段,確定最終返回結(jié)果的內(nèi)容項(xiàng).如“select name,tagtype,compress”表示需要返回測點(diǎn)的名稱、測點(diǎn)類型以及是否壓縮等信息.
根據(jù)from后的字段,確定查詢的是點(diǎn)信息或者是值信息.如“from upoint”表示查詢的是點(diǎn)信息,而“from uvalue”表示返回的是值信息,具體是何種值還需進(jìn)一步判斷.
解析Where后的信息,獲得UAPI函數(shù)調(diào)用時(shí)的參數(shù).按照變量、常量、子查詢、關(guān)系操作符、bool值的分類方法,對每個(gè)分詞進(jìn)行處理.
變量確定給出的信息類型,常量確定信息的具體值.對于id以范圍給出的(between A and B等形式),拆封成單個(gè)具體數(shù)值.涉及時(shí)間的,轉(zhuǎn)換成海量平臺所用時(shí)區(qū)的時(shí)間.如“where id between 100 and 135” id是變量,100和135是常量,id區(qū)間根據(jù)UAPI的調(diào)用規(guī)則轉(zhuǎn)換成100,101,102,…,135的形式.
對于包含子查詢的,先執(zhí)行子查詢并將結(jié)果傳遞給父查詢.涉及關(guān)系操作符和bool值的,需要將兩側(cè)的信息分別遞歸處理.如“where id=100 or id=109”‘or’是bool值,需要將兩側(cè)信息‘id=100’和‘id=109’分別遞歸到where子句層繼續(xù)處理.
增加mode和step字段.根據(jù)mode字段的值區(qū)分查詢測點(diǎn)值的具體形式(實(shí)時(shí)值、插值、斷面和原始值).對于查詢差值的,根據(jù)step字段確定每次的查詢步長.如“mode=3 and step=1500”表示查詢的是差值,且查詢步長是1500ms.
綜合來看,SQL語句“select * from uvalue where id=4000000 or id=4000001 and time > ‘2016-02-25 16:47:50.10’ and time < ‘2016-02-25 16:50:52.10’ and mode=3 and step=1000;” 表示查詢id為4000000和4000001的測點(diǎn)在‘2016-02-25 16:47:50.10’和‘2016-02-25 16:50:52.10’時(shí)間段內(nèi)的差值信息,查詢步長為1000 ms.
創(chuàng)建外部表,執(zhí)行create foreign table語句,為每個(gè)需要訪問的遠(yuǎn)程表創(chuàng)建外部表.在本系統(tǒng)中就是創(chuàng)建外部點(diǎn)表和外部值表.
正確執(zhí)行上述步驟后,大數(shù)據(jù)訪問插件即安裝完成.在大數(shù)據(jù)端可以通過SQL語句訪問底層的實(shí)時(shí)數(shù)據(jù)了.
為了驗(yàn)證SQL引擎功能的正確性,基于海量平臺進(jìn)行了相關(guān)的測試.
測試中,選用的海量平臺中關(guān)系庫表有3000萬條數(shù)據(jù)[10].
海量平臺存儲了大量有價(jià)值的歷史數(shù)據(jù),采用大數(shù)據(jù)手段對數(shù)據(jù)進(jìn)行分析處理能夠最大限度利用數(shù)據(jù)的價(jià)值.如果采用API接口的方式從海量平臺獲取數(shù)據(jù)將會增加程序的復(fù)雜度和開發(fā)難度,而本文的SQL引擎可以讓大數(shù)據(jù)平臺通過SQL的方式訪問海量平臺數(shù)據(jù),降低了開發(fā)難度.
為了驗(yàn)證功能,進(jìn)行了如下的實(shí)驗(yàn).實(shí)驗(yàn)中海量平臺中實(shí)時(shí)庫存儲了9000萬測點(diǎn),每個(gè)測點(diǎn)均有兩年左右歷史數(shù)據(jù),總數(shù)據(jù)量超過5 TB.
圖6為查詢兩個(gè)測點(diǎn)1個(gè)小時(shí)內(nèi)數(shù)據(jù),測點(diǎn)數(shù)據(jù)頻率為15分鐘,結(jié)果如圖所示.從圖中可以看出SQL語句能夠完整的獲取所需的數(shù)據(jù),并且耗時(shí)0.08秒,在功能和性能方面均有很強(qiáng)的實(shí)用價(jià)值.
圖6 直接獲取海量平臺1個(gè)小時(shí)測點(diǎn)數(shù)據(jù)
圖7為查詢兩個(gè)測點(diǎn)1個(gè)月內(nèi)數(shù)據(jù),測點(diǎn)與圖6相同,結(jié)果如圖所示.當(dāng)數(shù)據(jù)量很大時(shí),可通過異步輪循的方式獲取實(shí)時(shí)數(shù)據(jù).
圖7 直接獲取海量平臺一個(gè)月測點(diǎn)數(shù)據(jù)
通常,為了挖掘數(shù)據(jù)價(jià)值,需要將海量平臺實(shí)時(shí)數(shù)據(jù)與關(guān)系數(shù)據(jù)庫中電網(wǎng)檔案模型數(shù)據(jù)相結(jié)合.測試中,SQL引擎需要從海量平臺關(guān)系數(shù)據(jù)庫獲取電網(wǎng)檔案數(shù)據(jù),然后再從海量平臺中實(shí)時(shí)數(shù)據(jù)庫獲取量測數(shù)據(jù).
如圖8為從關(guān)系庫獲取測點(diǎn)信息后,再從海量平臺實(shí)時(shí)庫獲取數(shù)據(jù).圖中SQL語句執(zhí)行流程為,SQL引擎將查詢語句提交到另一個(gè)關(guān)系庫獲取測點(diǎn)信息后,將測點(diǎn)信息傳入SQL引擎,通過SQL引擎獲取海量平臺中實(shí)時(shí)數(shù)據(jù).圖8中SQ語句獲取的數(shù)據(jù)與圖6一致.
圖8 從關(guān)系庫中獲取測點(diǎn)信息后再從海量平臺獲取1個(gè)小時(shí)測點(diǎn)數(shù)據(jù)
圖9為獲取1個(gè)月數(shù)據(jù),數(shù)據(jù)與圖7一致,也可通過輪循的方式獲取SQL結(jié)果集數(shù)據(jù).
圖9 從關(guān)系庫中獲取測點(diǎn)信息后再從海量平臺獲取1個(gè)月測點(diǎn)數(shù)據(jù)
通過以上測試可以說明本文的SQL引擎在功能和性能上都滿足文中提出的通過SQL方式獲取海量平臺數(shù)據(jù)并提供給大數(shù)據(jù)平臺使用的要求.
針對電網(wǎng)運(yùn)用中,大數(shù)據(jù)服務(wù)平臺訪問海量平臺中數(shù)據(jù)的問題,本文設(shè)計(jì)了基于PostgreSQL的訪問方案.設(shè)計(jì)了大數(shù)據(jù)接口模塊的整體架構(gòu),詳細(xì)給出了海量平臺FDW模塊的設(shè)計(jì)思路與主要流程.采用隨機(jī)抽樣的方式估算外部值表的大小,結(jié)合本系統(tǒng)的查詢需求,對SQL語句進(jìn)行補(bǔ)充改造以及語義分析.利用本文的SQL引擎,上層Spark等大數(shù)據(jù)工具可以SQL的方式成功訪問底層海量平臺的數(shù)據(jù).目前,SQL引擎已集成到南方電網(wǎng)海量準(zhǔn)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺中,大數(shù)據(jù)應(yīng)用可通過SQL引擎訪問海量平臺底層實(shí)時(shí)數(shù)據(jù),極大的提高了數(shù)據(jù)資源的利用效率.