刁海洋
(西門子(中國(guó))有限公司上海分公司,上海 200082)
工控安全態(tài)勢(shì)感知系統(tǒng)不僅關(guān)系著工廠內(nèi)設(shè)備和網(wǎng)絡(luò)的安全,對(duì)工廠的整體安全管理、決策控制都有著非常重要的影響。如何保證工控安全態(tài)勢(shì)感知系統(tǒng)及時(shí)有效地反映設(shè)備和網(wǎng)絡(luò)的安全狀態(tài),保證統(tǒng)計(jì)分析類的數(shù)據(jù)及時(shí)得到處理,這些問題在態(tài)勢(shì)感知類的系統(tǒng)中受到極大關(guān)注,如何對(duì)數(shù)據(jù)挖掘和分析的處理任務(wù)進(jìn)行協(xié)調(diào)和調(diào)度成為必須解決的難題。時(shí)間輪算法的出現(xiàn)對(duì)于解決工控態(tài)勢(shì)安全感知系統(tǒng)中的關(guān)鍵問題有著非常重大的意義。
工控安全態(tài)勢(shì)感知系統(tǒng)問題通常涉及多個(gè)維度,但是其最根本問題是對(duì)數(shù)據(jù)的挖掘和分析任務(wù)進(jìn)行有效的管理,包括定時(shí)任務(wù)的類別和數(shù)量、定時(shí)任務(wù)的協(xié)調(diào)和調(diào)度、定時(shí)任務(wù)的分布式管理等問題[1]。
工業(yè)安全環(huán)境下,有大量的設(shè)備數(shù)據(jù)和網(wǎng)絡(luò)流量需要被采集、存儲(chǔ)和分析,包括設(shè)備的基本信息、應(yīng)用數(shù)據(jù)、系統(tǒng)日志、協(xié)議解析日志、事件日志以及網(wǎng)絡(luò)的流量數(shù)據(jù)等,這些數(shù)據(jù)都需要被存儲(chǔ)到存儲(chǔ)引擎中。在工控安全態(tài)勢(shì)感知系統(tǒng)中,以Elastic Search作為原始數(shù)據(jù)存儲(chǔ)引擎[2],為安全審計(jì)和上層的業(yè)務(wù)邏輯處理提供服務(wù)。對(duì)于這些種類繁多的數(shù)據(jù),需要按照面向?qū)ο笤O(shè)計(jì)的思想,采用多種不同的定時(shí)任務(wù)進(jìn)行處理。比如對(duì)于事件類型的日志,系統(tǒng)的事件種類也分多種,如嘗試連接事件、系統(tǒng)登錄事件等,對(duì)于不同的事件上層業(yè)務(wù)需求是不同的,那么就需要開發(fā)大量的定時(shí)任務(wù)進(jìn)行業(yè)務(wù)邏輯處理,這就導(dǎo)致了在整個(gè)系統(tǒng)中定時(shí)任務(wù)的類別和數(shù)量較多。
在系統(tǒng)中,有些任務(wù)需要每隔一段時(shí)間執(zhí)行的,有些任務(wù)有前后依賴關(guān)系,有些任務(wù)需要在執(zhí)行一段時(shí)間之后根據(jù)業(yè)務(wù)邏輯判斷是否取消。雖然在Java官方提供的框架中,有一些專門用來處理定時(shí)任務(wù)協(xié)調(diào)的工具,比如Timer,Scheduled Executor Service,這些工具的調(diào)度時(shí)間復(fù)雜度為O(LogN)級(jí)別。當(dāng)包含著業(yè)務(wù)邏輯的定時(shí)任務(wù)類別和數(shù)量都很多時(shí),這些工具的自身調(diào)度耗時(shí)將會(huì)影響到定時(shí)任務(wù)實(shí)際執(zhí)行的有效周期,進(jìn)而會(huì)影響到任務(wù)本身。如何對(duì)這些任務(wù)進(jìn)行高效的協(xié)調(diào)和調(diào)度非常關(guān)鍵。
為了保證服務(wù)的高可用性,工控安全態(tài)勢(shì)感知系統(tǒng)是以分布式的方式在工廠內(nèi)部署,各個(gè)服務(wù)是以多個(gè)服務(wù)器來均衡處理前端和數(shù)據(jù)計(jì)算層的服務(wù)請(qǐng)求,這些服務(wù)器以哈希的方式接收相應(yīng)的請(qǐng)求,執(zhí)行業(yè)務(wù)邏輯并返回結(jié)果。定時(shí)任務(wù)分散在各個(gè)服務(wù)器中,以特定的條件來觸發(fā)和執(zhí)行。那么,在分布式的環(huán)境下,如何保障這些大量的定時(shí)任務(wù)能夠定期有序地在服務(wù)器之間調(diào)度和執(zhí)行,不會(huì)重復(fù)和遺漏,是個(gè)重要的任務(wù)管理問題。
在定時(shí)任務(wù)體系架構(gòu)中,有多種調(diào)度框架和工具,比如前文提及的Timer,除此之外業(yè)界常見的還有時(shí)間輪、Quartz、Elastic-Job、XXL-JOB、Spring Task等[3]。在這些框架和工具中,有些在單機(jī)環(huán)境下以鏈表的方式按照?qǐng)?zhí)行順序來存儲(chǔ)定時(shí)任務(wù),然后按照Native的wait方式執(zhí)行時(shí)間的流動(dòng)和判斷,有些則是在分布式環(huán)境下以數(shù)據(jù)庫(kù)或者Zookeeper來協(xié)調(diào)分布式定時(shí)任務(wù)的執(zhí)行。單機(jī)環(huán)境下的定時(shí)任務(wù)調(diào)度工具側(cè)重于任務(wù)調(diào)度相關(guān)的效率和可靠性,在此基礎(chǔ)之上向使用者提供便捷的配置管理;分布式環(huán)境下的定時(shí)任務(wù)調(diào)度工具則更關(guān)注多個(gè)服務(wù)器之間如何同步定時(shí)任務(wù)的狀態(tài)信息,一般都是通過第三方組件來執(zhí)行狀態(tài)信息的管理。
以環(huán)形的隊(duì)列作為時(shí)間格(Timing Wheel),每個(gè)時(shí)間格上掛載著以雙向鏈表數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)的任務(wù)列表,雙向鏈表中的每一個(gè)元素表示需要執(zhí)行的任務(wù)項(xiàng),這些任務(wù)項(xiàng)的執(zhí)行時(shí)間一致,省去了任務(wù)調(diào)度器逐個(gè)判斷任務(wù)執(zhí)行時(shí)間的開銷。通過表盤指針指向當(dāng)前時(shí)間所在的位置,當(dāng)指針指向到某一個(gè)時(shí)間格時(shí),則任務(wù)調(diào)度器就將該鏈表上的所有任務(wù)取出執(zhí)行。當(dāng)需要增加新的定時(shí)任務(wù)時(shí),根據(jù)當(dāng)前指針位置和定時(shí)任務(wù)的時(shí)間偏移量,將該任務(wù)加入對(duì)應(yīng)的時(shí)間格的任務(wù)鏈表,通過尾部指針的指向?qū)⑷蝿?wù)添加到雙向鏈表的末端。同時(shí)以“時(shí)間格×?xí)r間跨度”作為當(dāng)前的時(shí)間輪的總時(shí)間跨度,當(dāng)某些任務(wù)的時(shí)間偏移量超過當(dāng)前時(shí)間輪的總時(shí)間跨度時(shí),增加多層時(shí)間輪,通過時(shí)間輪之間的層次關(guān)系以及任務(wù)的升維和降維,來標(biāo)志系統(tǒng)中所有的待執(zhí)行定時(shí)任務(wù)。
從上述實(shí)現(xiàn)原理可以看出,任務(wù)的寫入和執(zhí)行的時(shí)間復(fù)雜度都是以O(shè)(1)為常數(shù)級(jí)。通過多層時(shí)間輪的方式進(jìn)行時(shí)間的分層,以執(zhí)行的時(shí)間為單元對(duì)任務(wù)進(jìn)行劃分,將任務(wù)按照所屬時(shí)間輪掛載到對(duì)應(yīng)位置。隨著時(shí)間的流轉(zhuǎn),多層時(shí)間輪上掛載的任務(wù)升級(jí)或者降級(jí)到對(duì)應(yīng)層級(jí)的時(shí)間輪位置,這種方式減少了任務(wù)的執(zhí)行時(shí)間和系統(tǒng)當(dāng)前時(shí)間的對(duì)比次數(shù)。除此之外,每個(gè)任務(wù)被固定以雙向鏈表的方式掛載在時(shí)間格中,當(dāng)需要對(duì)任務(wù)進(jìn)行新增、刪除、修改和查詢時(shí),在雙向鏈表這種數(shù)據(jù)結(jié)構(gòu)上,可以很方便地執(zhí)行相應(yīng)操作,減少調(diào)度指針前進(jìn)和回溯的次數(shù)。最后,當(dāng)需要執(zhí)行任務(wù)的時(shí)候整條鏈表都會(huì)被執(zhí)行,省去了類似于Timer這些工具中的判斷時(shí)間。時(shí)間輪算法的低復(fù)雜度能夠顯著降低任務(wù)調(diào)度工具的時(shí)間開銷,提高調(diào)度效率,非常適合定時(shí)任務(wù)數(shù)量較多的場(chǎng)景。
圖1 基于時(shí)間輪算法的定時(shí)任務(wù)調(diào)度
業(yè)界主流的Kafka,Dubbo,ZooKeeper,Netty,Caffeine,Akka等框架都有時(shí)間輪算法的應(yīng)用。這些框架中有著較多的延時(shí)執(zhí)行操作,比如延時(shí)拉取、延時(shí)刪除、延時(shí)選舉、心跳檢測(cè)、超時(shí)處理等任務(wù),這些任務(wù)在大容量、高并發(fā)的場(chǎng)景下,對(duì)調(diào)度時(shí)間有著非常高的要求。比如Kafka單機(jī)環(huán)境下最大每秒能生產(chǎn)和消費(fèi)百萬(wàn)條消息,能夠同時(shí)支持2萬(wàn)個(gè)客戶端同時(shí)連接,這種情況下需要處理的定時(shí)任務(wù)將會(huì)非常多,而這些任務(wù)都依賴于底層的定時(shí)任務(wù)調(diào)度器進(jìn)行處理。時(shí)間輪算法能夠非常高效地協(xié)調(diào)和調(diào)度這些任務(wù),為框架應(yīng)用的持續(xù)高性能運(yùn)行提供保障。
將時(shí)間輪算法應(yīng)用到工控安全態(tài)勢(shì)感知系統(tǒng)之中,對(duì)時(shí)間輪算法的邏輯進(jìn)行二次開發(fā),根據(jù)業(yè)務(wù)的要求配置時(shí)間輪的間隔和輪數(shù),重新實(shí)現(xiàn)任務(wù)調(diào)度的邏輯,對(duì)特定的業(yè)務(wù)進(jìn)行適當(dāng)?shù)亩ㄖ聘脑?,將時(shí)間輪算法與原有系統(tǒng)的業(yè)務(wù)以模塊化的方式組合在一起,類似于微服務(wù)的形式,對(duì)時(shí)間輪算法模塊的修改和發(fā)布不影響原有業(yè)務(wù)系統(tǒng)的正常運(yùn)行。在實(shí)現(xiàn)二次開發(fā)和模塊化之后,任務(wù)調(diào)度模塊可以更好地協(xié)調(diào)和調(diào)度工控安全態(tài)勢(shì)感知系統(tǒng)中大量存在的統(tǒng)計(jì)分析定時(shí)任務(wù),除此之外將原先采用的Spring Task的Scheduled分散處理方式改為集中化管理,定時(shí)任務(wù)需要先向任務(wù)調(diào)度模塊注冊(cè)之后才能運(yùn)行,最后將任務(wù)調(diào)度模塊的具體任務(wù)調(diào)度邏輯與Redis的分布式鎖結(jié)合在一起,通過引入第三方組件的方式解決分布式場(chǎng)景下定時(shí)任務(wù)的調(diào)度和執(zhí)行問題。
圖1描繪了引入時(shí)間輪算法之后任務(wù)調(diào)度模塊的設(shè)計(jì),系統(tǒng)初始化時(shí)有3層時(shí)間輪,將每層時(shí)間輪設(shè)置為20格,以秒為基本單位,第一層時(shí)間輪的范圍為0~20 s,第二層時(shí)間輪的范圍為20~400 s,第三層時(shí)間輪的范圍為400~8 000 s。在運(yùn)行過程中時(shí)間輪的層數(shù)根據(jù)任務(wù)的分配時(shí)間動(dòng)態(tài)擴(kuò)展,當(dāng)系統(tǒng)中需要調(diào)度的時(shí)間超過8 000 s,則會(huì)增加第四層時(shí)間輪,以此類推直至可配置的最大范圍。在每層對(duì)應(yīng)時(shí)間格上掛載相應(yīng)的定時(shí)任務(wù)雙向鏈表,每個(gè)鏈表上的任務(wù)都相應(yīng)加了Redis的分布式鎖,各個(gè)任務(wù)的鎖都不相同,以任務(wù)的唯一ID作為區(qū)分。在取出雙向鏈表的所有任務(wù)并調(diào)度到其中某一個(gè)時(shí),調(diào)度模塊將該任務(wù)上的鎖與Redis中的鎖進(jìn)行對(duì)比判斷是否執(zhí)行該任務(wù)。
在工控安全態(tài)勢(shì)感知系統(tǒng)中,由于原始數(shù)據(jù)存儲(chǔ)在Elastic Search存儲(chǔ)引擎中,上層業(yè)務(wù)需要使用大量的定時(shí)任務(wù)從原始數(shù)據(jù)中挖掘出業(yè)務(wù)需要的信息。原先的設(shè)計(jì)使用的是實(shí)時(shí)聚合和少量的定時(shí)任務(wù)挖掘來實(shí)現(xiàn)統(tǒng)計(jì)和分析型的業(yè)務(wù),這種方式導(dǎo)致了在數(shù)據(jù)量增長(zhǎng)之后系統(tǒng)響應(yīng)時(shí)間變長(zhǎng)。在引入時(shí)間輪算法之后,對(duì)統(tǒng)計(jì)分析型的任務(wù)進(jìn)行拆解和分層。根據(jù)不同的業(yè)務(wù)類型,對(duì)系統(tǒng)事件、網(wǎng)絡(luò)流量、資產(chǎn)變化等不同的業(yè)務(wù)劃分多個(gè)類別,對(duì)于不同的類別再以時(shí)間的維度做進(jìn)一步的分層。在整個(gè)統(tǒng)計(jì)分析任務(wù)分層過程中,以5秒鐘、分鐘、小時(shí)、天、周、月、季度或年為單位進(jìn)行分層[4],將這個(gè)層級(jí)的概念下沉到時(shí)間輪算法的實(shí)現(xiàn)模塊中。由于每種類型的業(yè)務(wù)對(duì)應(yīng)不同的定時(shí)任務(wù),還需要再進(jìn)行對(duì)應(yīng)時(shí)間的分層,那么整體定時(shí)任務(wù)的數(shù)量就會(huì)大幅增長(zhǎng),時(shí)間輪算法能夠非常好地處理大量的定時(shí)任務(wù),保證系統(tǒng)的穩(wěn)定運(yùn)行。
在之前的設(shè)計(jì)中,采用的是Spring Task的Scheduled方式,在各個(gè)需要定時(shí)執(zhí)行的業(yè)務(wù)代碼的位置加上需要定時(shí)處理的注解,就會(huì)將調(diào)度的邏輯交給Spring框架來處理,這種方式非常簡(jiǎn)單便捷,但是帶來了管理上的問題。引入時(shí)間輪算法之后,設(shè)計(jì)了獨(dú)立的模塊,各個(gè)需要執(zhí)行定時(shí)任務(wù)的位置都需要在該模塊中注冊(cè),只有在注冊(cè)之后才能將定時(shí)任務(wù)交由時(shí)間輪來調(diào)度和執(zhí)行。在注冊(cè)的子模塊中,會(huì)對(duì)所有注冊(cè)了的定時(shí)任務(wù)進(jìn)行權(quán)限的識(shí)別、行為的記錄,便于后續(xù)對(duì)定時(shí)任務(wù)的集中化管理,比如在界面上由管理員手工取消、重啟。在交由時(shí)間輪算法實(shí)現(xiàn)模塊集中化管理之后,之前隱藏在代碼邏輯中的定時(shí)任務(wù)完全交由該模塊來管理,任務(wù)的執(zhí)行和調(diào)度不再受制于業(yè)務(wù)模塊,整體設(shè)計(jì)上契合面向?qū)ο蠼怦畹乃枷搿?/p>
在工控安全態(tài)勢(shì)感知系統(tǒng)中,實(shí)際的部署場(chǎng)景包含分布式多機(jī)部署,后臺(tái)服務(wù)被同時(shí)部署到多臺(tái)服務(wù)器中以實(shí)現(xiàn)負(fù)載均衡,定時(shí)任務(wù)也就會(huì)被分散在各個(gè)服務(wù)器中。在之前的設(shè)計(jì)中,將定時(shí)任務(wù)集中部署在某一臺(tái)服務(wù)器單獨(dú)運(yùn)行,如果該服務(wù)器宕機(jī)就會(huì)導(dǎo)致整體定時(shí)任務(wù)出現(xiàn)問題。而單獨(dú)的時(shí)間輪算法僅支持單機(jī)環(huán)境下的定時(shí)任務(wù)執(zhí)行,無(wú)法對(duì)分布式場(chǎng)景下的定時(shí)任務(wù)進(jìn)行調(diào)度。在這種場(chǎng)景下,額外引入Redis分布式鎖的技術(shù)[5]。當(dāng)時(shí)間指針轉(zhuǎn)動(dòng)到需要執(zhí)行定時(shí)任務(wù)的時(shí)間格時(shí),需要先將該鏈表上所有任務(wù)取出來,逐個(gè)判斷該任務(wù)是否已經(jīng)在Redis中加上執(zhí)行鎖;如果已經(jīng)加上則在當(dāng)前服務(wù)器上放棄執(zhí)行,否則在Redis上加上新的執(zhí)行鎖,表明當(dāng)前已經(jīng)在執(zhí)行,其他服務(wù)器輪轉(zhuǎn)到該任務(wù)時(shí),就會(huì)發(fā)現(xiàn)該任務(wù)正在被執(zhí)行而直接跳過。這樣,時(shí)間輪算法和Redis分布式鎖技術(shù)的結(jié)合可實(shí)現(xiàn)分布式場(chǎng)景下的定時(shí)任務(wù)調(diào)度。
本文對(duì)如何保證工控安全態(tài)勢(shì)感知系統(tǒng)中定時(shí)任務(wù)的高效率調(diào)度進(jìn)行了分析和研究。在西門子工廠實(shí)際部署前后的對(duì)比研究表明,將時(shí)間輪算法應(yīng)用到工控安全態(tài)勢(shì)感知系統(tǒng)中,能夠有效提高系統(tǒng)的運(yùn)行效率,保證任務(wù)持續(xù)穩(wěn)定地運(yùn)行,為用戶提供了安全穩(wěn)定的使用環(huán)境。在工業(yè)互聯(lián)網(wǎng)環(huán)境下,工控安全態(tài)勢(shì)感知技術(shù)已成為工業(yè)安全應(yīng)用趨勢(shì),時(shí)間輪算法發(fā)揮著重大的作用。