周 航,莫 同,李偉平,盧思遠
(北京大學(xué) 軟件微電子學(xué)院,北京 100871)
隨著物聯(lián)網(wǎng)的發(fā)展,很多應(yīng)用場景下的被動服務(wù)提升為主動服務(wù).主動服務(wù)無需人來驅(qū)動,由系統(tǒng)自動采集數(shù)據(jù),根據(jù)邏輯進行判斷,然后主動提供如信息檢索、智能管理等典型應(yīng)用服務(wù),極大減少了人力成本,同時提高了服務(wù)觸發(fā)的及時性和準確性[3].情景感知(context aware)是實現(xiàn)主動服務(wù)的一種主流方式[1],“情境”和“情境感知”被定義為“位置、人和物體周圍的標識以及這些物體的變化”[2],通??梢杂们榫硨傩詠碇复@些物理或者社會性的特征和信息.相應(yīng)的情境感知即指對這些情境屬性的獲取和處理過程[1].
在之前的相關(guān)工作中,我們?yōu)槿珖鞯囟鄠€糧庫的儲糧過程中的通風(fēng)、制冷和殺毒等需求以及大樓的安防監(jiān)控等需求分別建立了情境感知模型[4,5].在這些情境模型中,我們定義了情境屬性,并劃分出不同場景,指定當場景下的情境屬性符合某個規(guī)則時需要觸發(fā)的服務(wù).在實現(xiàn)層面,引擎是非常重要,良好的引擎可以主動適應(yīng)規(guī)則變化,幫助人們以很低的成本來高效準確的管理復(fù)雜的情境感知系統(tǒng),因此引擎的設(shè)計面臨許多技術(shù)上的挑戰(zhàn).一方面,引擎要支持各種語義表達(業(yè)務(wù)邏輯的描述)的解析與執(zhí)行.另一方面,由于傳感器自動采集數(shù)據(jù)的數(shù)量和頻次較高,引擎在面對大數(shù)據(jù)量時需要具備較好的處理性能.相關(guān)研究[6,7]為此提出了由事件驅(qū)動的可擴展的設(shè)計方案,我們學(xué)習(xí)并測試了這些方案的可行性,并調(diào)研了市場上的幾款開源規(guī)則引擎如Drools、JRuleEngine[8,9],并嘗試將處理規(guī)則匹配的操作托付給它們.以Drools為例,它是一個基于Java的開源規(guī)則引擎,可以將復(fù)雜多變的規(guī)則從硬編碼中解放出來,以規(guī)則腳本的形式存放在文件中,使得規(guī)則的變更不需要修正代碼重啟機器就可以立即在線上環(huán)境生效[10,11].但在實際開發(fā)過程當中,Drools等規(guī)則引擎并不能很好的滿足實際的業(yè)務(wù)需求.第一,Drools的表達能力較弱.Drools的規(guī)則文件僅支持符合自然語義的規(guī)則定義,不能夠完整、準確地描述一個情境模型,如原始傳感器數(shù)據(jù)到情境屬性的映射關(guān)系、情境規(guī)則和場景的從屬關(guān)系等.第二,Drools在執(zhí)行時存在性能瓶頸.在情境模型中,每一條規(guī)則都包含在一個具體場景下,而Drools在執(zhí)行前并不能將數(shù)據(jù)定位到其從屬的場景下,這導(dǎo)致每一條傳感器數(shù)據(jù)在執(zhí)行過程中都將遍歷所有規(guī)則并進行匹配,在處理短時間密集傳入的傳感器數(shù)據(jù)時存在不可容忍的時間損耗.對此我們的工作目標是設(shè)計并實現(xiàn)一個情境感知引擎,它具備更好的模型描述能力,如定義場景下賦值條件、處理傳感器數(shù)據(jù)的時序邏輯等.同時在執(zhí)行過程中可以通過緩存服務(wù)、場景構(gòu)造等方法快速定位到當前數(shù)據(jù)匹配的場景下,提升性能.
本文第1節(jié)介紹了研究背景,對相關(guān)的情境感知模型以及規(guī)則引擎的研究現(xiàn)狀進行回顧和分析,提出了情景感知引擎的設(shè)計目標.第2節(jié)介紹了引擎的內(nèi)部各個模塊的作用及整體的執(zhí)行流程.第3節(jié)解釋了一個標準的模型文件的組成.第4節(jié)詳細解釋了后端引擎在獲取傳感器數(shù)據(jù)后進行場景構(gòu)造、場景定位、規(guī)則匹配和服務(wù)觸發(fā)的具體流程.第5節(jié)從幾個角度對所提出的方案和進行仿真實驗,最后在第6節(jié)給出本文的結(jié)論和未來的工作.
主動服務(wù)要想能夠?qū)崿F(xiàn),需要一個計算機可理解的業(yè)務(wù)邏輯來自動執(zhí)行.模型相當于把業(yè)務(wù)表述成計算機可執(zhí)行的業(yè)務(wù)邏輯,典型的模型可以被組織成如結(jié)構(gòu)化文檔XML等格式.用戶首先通過圖形化的建模工具完成建模,之后通過接口將模型文件輸入引擎解析并存儲.當傳感器采集到數(shù)據(jù)時,該條數(shù)據(jù)被輸入引擎,根據(jù)模型(業(yè)務(wù)邏輯)對實時數(shù)據(jù)進行處理,判斷是否滿足服務(wù)調(diào)用條件,若滿足則調(diào)用,實現(xiàn)主動服務(wù).引擎統(tǒng)計服務(wù)觸發(fā)率、數(shù)據(jù)吞吐率等信息并上報給監(jiān)視器供用戶分析和實時調(diào)整,系統(tǒng)結(jié)構(gòu)如圖1所示.
圖1 情境感知系統(tǒng)Fig.1 Context-aware system
引擎內(nèi)部的模塊結(jié)構(gòu)如圖2所示.引擎主要分為兩三個部分,解析器、執(zhí)行器和監(jiān)視器.對于建模工具輸入的xml文件,由解析器中的XML Parser和Rule Parser共同完成完成解析,并將結(jié)果送入ModelStore,后者使用內(nèi)部的數(shù)據(jù)結(jié)構(gòu)存儲模型信息,并與執(zhí)行器交互.XML Parser負責解析模型中原始數(shù)據(jù)、場景、屬性、規(guī)則、服務(wù)的定義,同時記錄他們之間的對應(yīng)關(guān)系,維護索引.Rules Parser則負責處理模型中定義的規(guī)則并生成規(guī)則文件供Drools在執(zhí)行時調(diào)用.考慮到用戶可能不具備很好的編程基礎(chǔ),Rules Parser能夠處理一些不符合drools語法的規(guī)則,如括號的自動補全、邏輯表達式寫法的糾正、錯誤變量命名的修正等,并在不能夠修正的情況下給予提示反饋.
在執(zhí)行器部分,引擎通MQListener訂閱底層的消息隊列MQ,對于每一條從消息隊列中獲取的傳感器數(shù)據(jù),將其輸入Mappings模塊完成原始數(shù)據(jù)到情境屬性的映射上.通過SceneConstructor完成相關(guān)聯(lián)場景的構(gòu)造和匹配,這個過程依賴于緩存服務(wù)Cache來獲取數(shù)據(jù)快照.對于匹配場景下定義的規(guī)則,RulesEngine為規(guī)則內(nèi)屬性賦值并執(zhí)行,在規(guī)則滿足條件的情況下通過ServiceTrigger調(diào)用接口觸發(fā)對應(yīng)的外部服務(wù).具體一條傳感器數(shù)據(jù)處理的流程會在第5節(jié)詳細描述.
圖2 引擎架構(gòu)Fig.2 Engine architecture
整合進入引擎的監(jiān)控工具Monitor可以通過日志和外部接口來暴露引擎內(nèi)部的一些信息,如從ModelStore獲取引擎正在執(zhí)行的模型數(shù)量,其內(nèi)部的場景和規(guī)則數(shù)量.同時可以結(jié)合ModelStore和緩存Cache獲取具體某個場景實例內(nèi)的屬性值,以及該場景一段時間內(nèi)觸發(fā)的服務(wù).
在執(zhí)行過程中,為了能實現(xiàn)主動服務(wù),需要在模型中定義原始數(shù)據(jù)、屬性、場景、規(guī)則、服務(wù)等元素.通過對大樓監(jiān)控模型和糧庫通風(fēng)模型[3]的分析,我們提取出了這些元素之間的對應(yīng)關(guān)系,如圖3所示.
圖3 模型-原始數(shù)據(jù)-情境屬性-場景-規(guī)則-服務(wù)對應(yīng)關(guān)系Fig.3 Relation between model-raw data-attribute- scene-rule-service
圖3反映的這種層次結(jié)構(gòu)比較適合被組織成XML格式的文件,便于用戶核對以及后端引擎解析.每一個元素具體的定義以及在引擎中的處理方式如下.建模人員在其基礎(chǔ)上通過規(guī)范的建模過程就可以得到滿足不同需求的模型實例.
定義1.情境模型 Model
情境模型頭部描述了情境模型的基本信息,包括模型名稱和版本號,版本號便于引擎動態(tài)的更新modelStore中的模型信息.
定義2.原始數(shù)據(jù) Rawdata
原始數(shù)據(jù)是由消息隊列發(fā)布的一條傳感器數(shù)據(jù),會被存儲在Cache中.
定義3.情境屬性 Attribute
情境屬性由原始數(shù)據(jù)映射而來,描述系統(tǒng)中某個對象的狀態(tài).在執(zhí)行過程中主要由Mappings模塊負責處理原始數(shù)據(jù)到情境屬性的映射關(guān)系以及合法性判斷.dataType,range,rawDataId,mapping>定義了一個情境屬性.dataType 代表數(shù)據(jù)類型,如定義int整型則代表該屬性實例值可以進行數(shù)學(xué)運算.range 代表數(shù)據(jù)取值范圍,用于判斷數(shù)據(jù)的有效性,避免設(shè)備故障情況下非法的輸入數(shù)據(jù)對引擎造成的干擾.rawDataId標識出情境屬性將被從哪個原始數(shù)據(jù)映射得到.映射函數(shù)mapping通常是一個系統(tǒng)函數(shù),其內(nèi)部實現(xiàn)可以是一些復(fù)雜的運算操作,也可以是對外部接口的訪問.舉例來說,原始數(shù)據(jù)Rreader_F1為大樓一層讀卡器讀到的工卡號,通過Mappings(Rreader_F1)→Arole可以將工卡號這條原始數(shù)據(jù)映射到情境屬性”用戶身份”上,得到該情境屬性的實例值為“員工”或是“安保人員”,而這個映射過程需要以工卡號作為唯一的輸入,調(diào)用員工管理系統(tǒng)提供的外部接口得到.
定義4.場景 Scene
場景是一系列情境屬性匹配條件的集合,引擎中的SceneConstructor模塊負責與場景相關(guān)的操作.
表示溫度被限定在1~9攝氏度或者剛好為16攝氏度.
定義5.規(guī)則 Rule
規(guī)則是一種基于事件調(diào)用服務(wù)的邏輯.在建模過程中,建模人員選取在第一部分定義的情境屬性名,組合基本的邏輯表達式來定義符合自然語意的規(guī)則,這條規(guī)則最終會被引擎解析并被Rules Parser處理成符合Drools語法的drl規(guī)則文件,如(Ci1-Ci2>0).
定義6.服務(wù) Service
服務(wù)是一種可以被系統(tǒng)調(diào)用并具有一定功能的執(zhí)行流.例如,撥打語音電話給安保人員提醒其去某樓層巡視觀察即使一種即時消息通知服務(wù).服務(wù)的觸發(fā)由ServiceTrigger模塊完成,在觸發(fā)過程涉及對外部接口的調(diào)用.
表1 元模型與Drools規(guī)則文件表達能力對比
Table 1 Comparison of expression ability in Meta Model and Drools rule
表達元模型Drools規(guī)則流程控制(如if-else)支持支持數(shù)值計算(如a-b*c)支持支持邏輯運算(如a&&b)支持支持數(shù)值緩存(如數(shù)據(jù)有效期1s)支持不支持自定義函數(shù)(如時序邏輯)支持不支持業(yè)務(wù)細化(如定義場景、屬性)支持不支持
在一份模型文件被輸入到圖2引擎中的解析器后,除了規(guī)則定義部分會被移交給RuleParser模塊來處理成符合Drools語法的規(guī)則文件之外,其他部分都會交由XMLParser解析并存儲到modelStore當中,圖4描述了模型文件中各部分在modelStore當中的存儲關(guān)系,以及各部分在引擎中都將被哪個模塊處理.表1對比了元模型與Drools規(guī)則文件兩者的描述能力.
圖4 模型文件在ModelStore中的內(nèi)存結(jié)構(gòu)Fig.4 Digested model file in ModelStore
xml文件被Rules Parser和XML Parser處理后,除了提取各個元素節(jié)點并轉(zhuǎn)化成內(nèi)部的實例之外,還需要使用額外的內(nèi)存來維護圖3中正向和部分反向的對應(yīng)關(guān)系作為內(nèi)存中的索引,這些索引會在執(zhí)行過程中被頻繁使用.我們定義Set代表多個元素的合集
relation1:Rawdata → Attribute
relation2:Attribute → Set(Scene)
relation3;Scene → Set(Attribute)
relation4:Scene → Set(Rule)
relation5:Rule → Set(Service)
一條傳感器數(shù)據(jù)被送入MQ并發(fā)布給引擎的監(jiān)聽器后,首先通過relation1獲得與該原始數(shù)據(jù)對應(yīng)的情境屬性,通過用戶定義的Mapping映射函數(shù)映完成映射,并存入Cache,同時設(shè)置失效時間.接下來要構(gòu)造這個情境屬性以及其關(guān)聯(lián)屬性的數(shù)據(jù)快照SNAPSHOT[12,13].數(shù)據(jù)快照是在同一個時間節(jié)點下,所有相關(guān)聯(lián)情境屬性實例的一個瞬時值合集.通過relation2獲取所有和這個情境屬性關(guān)聯(lián)的場景Set(E),對于每一個場景,通過relation2獲取場景下相關(guān)聯(lián)的情境屬性集合Set(E).對于所有關(guān)聯(lián)的情境屬性,從Cache獲取緩存的同一時間間隔內(nèi)的傳感器數(shù)據(jù)存入快照,至此數(shù)據(jù)快照構(gòu)造完畢.之后進入場景構(gòu)造匹配以及規(guī)則執(zhí)行流程,對于Set(C)中的每個場景,送入SceneConstructor從快照當中取值構(gòu)造每個場景的實例,并進行場景匹配.SceneConstructor包含一個簡單的語法分析模塊,可以判斷一個情境屬性的實例是否滿足場景下匹配條件
在構(gòu)造場景和規(guī)則匹配過程中,如果出現(xiàn)涉及場景過多,特別是場景內(nèi)情境屬性過多的情況,SceneConstructor和RuleEngine的執(zhí)行過程會帶來一定的時間消耗.數(shù)據(jù)快照能夠保證引擎在執(zhí)行過程中所拿到數(shù)據(jù)是瞬時有效的而不是在執(zhí)行過程中被送入MQ或者被Cache當做失效值清理掉的空值,這樣SceneConstructor和RuleEngine執(zhí)行時延不會導(dǎo)致規(guī)則的誤觸發(fā)或者丟失觸發(fā),而會平滑的蔓延到服務(wù)觸發(fā)的時間節(jié)點.在涉及120個情境屬性的模型中,觸發(fā)時間的平均時延為12ms.這適用于一些可以容忍觸發(fā)服務(wù)當中中存在輕微時差的場景,如大樓門禁的報警服務(wù)、糧庫的自動通風(fēng)服務(wù)等.在需要做到瞬時觸發(fā)多個場景下多個服務(wù)的模型,如軍用作戰(zhàn)模型,則需要開發(fā)更高效的規(guī)則解析模塊代替SceneConstructor和RuleEngine.算法1描述了整體的執(zhí)行流程.
算法1.引擎處理傳感器數(shù)據(jù)過程.
//For each rawData
//phase One-construct snapshot
snapshot = new snapshot( );
attribute = relation1(rawData);
insertToRedis (atribute);
sceneSet = relation2(attribute);
foreach scene in sceneSet
attributeSet.add(relation3(scene));
foreach attr in attributeSet
snapshot.add(getFronRedis(attr));
// phase Two - go through all relevant scenes
foreach scene in sceneSet
sceneInstance = constructScene(scene,snapshot);
if (determinerMatch(sceneInstance,scene) == false)
continue;
ruleSet = relation4(scene);
foreach rule in ruleSet
ruleInstance = constructRule(rule,snapshot);
if(droolsMatch(ruleInstance,rule) == false)
continue;
serviceSet = relation5(rule);
foreach service in serviceSet
triggerService(service);
引擎被部署在一臺單核CPU 2.20 GHZ,內(nèi)存4G,操作系統(tǒng)版本為Centos 6.5 64位的服務(wù)器上.引擎內(nèi)部使用Maven來組織各個模塊,由Spring3.0 管理各個服務(wù)實例.緩存服務(wù)(Cache)使用Redis 3.2.6,消息隊列(MQ)使用ActiveMq 5.5.0,規(guī)則引擎(RuleEngine)使用Drools 6.5.0.使用單消息節(jié)點,主從結(jié)構(gòu)的Redis,使用全局的JedisPool連接池來加速與Redis的交互操作.同時緩存了Drools的會話連接和knowledgeBase,避免每次調(diào)用規(guī)則引擎都重新編譯drl規(guī)則文件.在模型更新時才去更新該全局的knowledgeBase.
我們通過兩個實驗來測試引擎的性能表現(xiàn).實驗1對比在使用sceneConstructor模塊劃分場景和完全使用Drools規(guī)則描述模型時數(shù)據(jù)處理效率的差異.實驗2測試場景下的賦值條件個數(shù)與數(shù)據(jù)處理效率的關(guān)系.
實驗1.在第3節(jié)元模型定義中提到每個場景內(nèi)部包含了該場景內(nèi)情境屬性所需滿足的條件,這些匹配條件將不同場景做劃分,作為可復(fù)用的公共條件縮短了規(guī)則的長度,同時可以幫助SceneConstructor模塊在數(shù)據(jù)處理過程中快速定位到某幾個場景下,減少Drools所需遍歷從屬規(guī)則的條數(shù).因此建模過程中這些賦值條件的數(shù)目和精確程度將極大影響引擎執(zhí)行的效率.假設(shè)總共有k1個場景,每個場景下平均定義了n個情境屬性的條件,每一個情境屬性平均會出現(xiàn)在k2個場景下,相同情境屬性在不同場景下的碰撞率為p(即一條數(shù)據(jù)對應(yīng)的情境屬性同時滿足兩個判斷條件的概率).那么對于一批符合場景1的數(shù)據(jù),其也滿足場景2所有判斷條件的概率s為
(1)
在k1=6,k2=3,p=0.5的取值下,n(0)→n(3) 帶來 S(1)→S(0.0156),極大減少了場景之間重合的概率(即相似度),減少了對Drools的輸入.因此可以初步推斷在定義一個場景E=
對此我們進行第一個實驗對以上推測進行驗證.我們首先構(gòu)造僅包含1個場景,場景下包含20條規(guī)則的情境模型送入引擎解析執(zhí)行,隨后開發(fā)測試腳本批量模擬傳感器數(shù)據(jù)送入消息隊列.每一條傳感器數(shù)據(jù)都會被控制在模型中原始數(shù)據(jù)定義的有效值范圍之內(nèi),并遵從泊松分布,目的是讓規(guī)則的觸發(fā)盡可能的隨機.我們統(tǒng)計在引擎執(zhí)行5分鐘當中處理一條傳感器數(shù)據(jù)平均耗時.之后分多次更新模型,在模型內(nèi)定義更多的場景并測試記錄.對于規(guī)則匹配后的服務(wù)觸發(fā)操作,因服務(wù)內(nèi)容不同而會受到網(wǎng)絡(luò)等外部因素的干擾,因此在測試過程中被省略.該部分測試完畢后,我們將模擬的每一個模型完全使用Drools規(guī)則文件描述,即將場景下的屬性條件判斷全部寫入Drools規(guī)則中.在處理時跳過SceneConstructor模塊,重復(fù)之前的測試步驟并記錄測試結(jié)果.
圖5 SceneConstructor帶來的性能提升Fig.5 Performance gains from SceneConstructor
圖5驗證了公式(1)的推導(dǎo)結(jié)果,可以初步得出結(jié)論,即劃分場景可以帶來性能的優(yōu)化,且隨著場景和規(guī)則數(shù)量的增多這種效率提升更為明顯.
實驗2.從算法1中可以發(fā)現(xiàn),隨Va的增多,每一條數(shù)據(jù)能夠關(guān)聯(lián)的場景數(shù)量也會增加,導(dǎo)致在Drools執(zhí)行前場景匹配階段中送入SceneConstructor的關(guān)聯(lián)屬性也在增加,反而帶來時間損耗.因此單純增加Va的個數(shù)并不能持續(xù)提升效率.為此我們進行了第二個實驗.我們用包含7個場景,20個情境屬性,30條規(guī)則的大樓模型進行測試.得到數(shù)據(jù)執(zhí)行效率與場景下屬性賦值條件Va的數(shù)量占該場景所有關(guān)聯(lián)屬性百分比α的關(guān)系,結(jié)果見圖6.
圖6 數(shù)據(jù)處理效率與場景下賦值條件占比的關(guān)系Fig.6 Relation between condition ratio and engine performance
當α=0%時,模型退化成為不為場景屬性賦值的情況,效率較差.隨著α上升,SceneConstructor模塊發(fā)揮作用使得效率提升,在α接近40%時效率達到最優(yōu).α超過40%后,執(zhí)行效率下降,在不同的模型中這個閾值不同.這個測試結(jié)果說明,在定義場景中屬性的判斷條件Va時,應(yīng)該盡量選取關(guān)鍵的,有區(qū)分性的情境屬性來構(gòu)造判斷條件,不能盲目的加入Va.如在大樓模型下的“辦公區(qū)”場景內(nèi),“樓層數(shù)”屬于比較有區(qū)分性的情境屬性,我們可以為其賦值Vfloor≥3,而“視野內(nèi)人數(shù)”雖然從屬于該場景,但并沒有為其構(gòu)造判斷條件如Vview_num≥0的必要.
本文提出了一種面向主動服務(wù)的情境感知引擎,與開源的規(guī)則引擎如Drools相比,該引擎可以支持更豐富的模型描述語言,同時在處理短時間內(nèi)大量數(shù)據(jù)時也表現(xiàn)出較好的執(zhí)行效率和準確率.在建模過程中,開發(fā)人員只需要為建模人員提供原始數(shù)據(jù)到情境屬性的映射函數(shù)Mappings,而建模人員通過建模工具提供的前端界面的組件拖拽、連線和簡單規(guī)則輸入即可完成模型建立,并將模型文件輸入引擎進行主動服務(wù).
引擎開發(fā)完成之后,在相關(guān)工作[4]中建立的儲糧模型和大樓監(jiān)控模型都已經(jīng)被移植到該系統(tǒng)上進行后續(xù)維護.在一些較為復(fù)雜的系統(tǒng)如軍用作戰(zhàn)系統(tǒng)中,情境感知系統(tǒng)需要提供更多的功能如場景之間的切換,規(guī)則之間的跳轉(zhuǎn),以及支持非瞬時場景下的規(guī)則觸發(fā),那么需要通過更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和執(zhí)行流,引入狀態(tài)機來實現(xiàn).同時當數(shù)據(jù)量過大,需要將系統(tǒng)部署在多機協(xié)同處理,這也是我們下一步面臨的挑戰(zhàn).