戴振邦 江恩杰 劉力嘉 甘江偉 戴振邦 江恩杰 劉力嘉 甘江偉
摘要:集中化,合并任務(wù)的處理是分布式設(shè)計(jì)中的一個(gè)難點(diǎn)。由于不同任務(wù)中需要頻繁的數(shù)據(jù)交換,且需對(duì)不同任務(wù)的結(jié)果進(jìn)行合并,使其難以使用目前主流的分布式設(shè)計(jì)模型。分布式管道設(shè)計(jì)模式是一種高度解耦合的分布式設(shè)計(jì)模型,適合處理業(yè)務(wù)粒度較大,數(shù)據(jù)交換頻發(fā),IO瓶頸較高的任務(wù)。文章在分布式管道設(shè)計(jì)模式的基礎(chǔ)上,參考服務(wù)發(fā)現(xiàn)機(jī)制實(shí)現(xiàn)了一個(gè)高性能的管道服務(wù)框架。
關(guān)鍵詞:分布式;服務(wù)發(fā)現(xiàn);動(dòng)態(tài)負(fù)載均衡;管道任務(wù);高解耦
中圖分類號(hào):TP311? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2096-4706(2021)07-0044-07
Design and Implementation of Pipeline Service Framework Based on
Distributed Pipeline Mode
DAI Zhenbang1,JIANG Enjie2,LIU Lijia2,GAN Jiangwei3
(1.School of Chemical Engineering,Northwest Minzu University,Lanzhou? 730124,China;
2.Information Engineering Department,Chengyi University College,Jimei University,Xiamen? 361021,China;
3.College of Physics and Electronic Information Engineering,Minjiang University,F(xiàn)uzhou? 350108,China)
Abstract:Centralization and combined task processing is a difficulty in distributed design. Due to there are frequent data exchanges in different tasks and the results of different tasks need to be merged,it is difficult to use the current mainstream distributed design model. Distributed pipeline design pattern is a high decoupling distributed design model,which is suitable for the tasks with large business granularity,frequent data exchange and high IO bottleneck. Based on the distributed pipeline design pattern,this paper implements a high performance pipeline service framework with the reference of service discovery mechanism.
Keywords:distributed;service discovery;dynamic load balancing;pipeline task;high decoupling
收稿日期:2021-03-09
基金項(xiàng)目:大學(xué)生創(chuàng)新創(chuàng)業(yè)訓(xùn)練計(jì)劃項(xiàng)目 (省級(jí))(202013471013)
0? 引? 言
目前比較流行的分布式解耦合的解決方案中,如微服務(wù),這是一種將應(yīng)用程序構(gòu)造為一組松散耦合服務(wù)的軟件開發(fā)技術(shù),是面向服務(wù)的體系結(jié)構(gòu)(Service-Oriented Architecture,SOA)架構(gòu)樣式的一種變體[1]。在微服務(wù)體系結(jié)構(gòu)中,其服務(wù)是細(xì)粒度的,并且協(xié)議是輕量級(jí)的[2],是一種高度解耦合的分布式設(shè)計(jì)思想,但微服務(wù)更適合用在解決模塊化可分離的任務(wù)中,可以在不同服務(wù)中通過(guò)相互調(diào)用的方式來(lái)完成不同服務(wù)中的協(xié)同。對(duì)于目前互聯(lián)網(wǎng)大多數(shù)分層業(yè)務(wù)來(lái)說(shuō),微服務(wù)是一個(gè)很好的解決辦法,但對(duì)于集中化的,需要合并處理任務(wù)來(lái)說(shuō),微服務(wù)無(wú)法有效地對(duì)任務(wù)進(jìn)行分層。本文參考分布式管道設(shè)計(jì)模式的解決方案,設(shè)計(jì)一個(gè)用于分層合并任務(wù)的分布式解耦合任務(wù)處理框架。
本文設(shè)計(jì)了一個(gè)分布式解耦合任務(wù)處理框架(下文簡(jiǎn)稱管道服務(wù)框架),主要解決分布式任務(wù)中的服務(wù)發(fā)現(xiàn)、動(dòng)態(tài)負(fù)載均衡和管道粒度的拆分,最后通過(guò)實(shí)際業(yè)務(wù)中的應(yīng)用效果驗(yàn)證了該框架的可行性和有效性。
1? 分布式管道設(shè)計(jì)模式
分布式管道設(shè)計(jì)模式是一種去中心化的分布式設(shè)計(jì)模式,其特點(diǎn)是無(wú)須任務(wù)分配,每個(gè)獨(dú)立的管道(總?cè)蝿?wù)的子集)都可以主動(dòng)或被動(dòng)地推送或接收數(shù)據(jù),并且按照一定的規(guī)則對(duì)數(shù)據(jù)進(jìn)行處理,然后執(zhí)行流出或者暫時(shí)儲(chǔ)存的操作,管道還可以截留數(shù)據(jù),在特定條件下對(duì)數(shù)據(jù)進(jìn)行合并流出。在管道設(shè)計(jì)模式中,管道可以根據(jù)數(shù)據(jù)的標(biāo)記,使用一種類似服務(wù)發(fā)現(xiàn)的方式主動(dòng)地推送數(shù)據(jù)到處理管道中,即對(duì)于任何一個(gè)產(chǎn)生的數(shù)據(jù),無(wú)須使用消息隊(duì)列等工具對(duì)任務(wù)進(jìn)行推送,只需要交付到任何一個(gè)管道的入口由管道進(jìn)行推送即可。
分布式管道設(shè)計(jì)模式中道管道類型有進(jìn)程管道、協(xié)程管道、線程管道,不同的管道維護(hù)不同的上下文,同時(shí)有不同的處理方案,相對(duì)來(lái)說(shuō),進(jìn)程管道做到了并行處理,適用于計(jì)算密集型任務(wù);協(xié)程管道適用于高IO任務(wù),可以幾乎不需要額外的消耗,進(jìn)行操作系統(tǒng)回調(diào)。
2? 管道服務(wù)框架架構(gòu)
如圖1所示,管道服務(wù)架構(gòu)中,服務(wù)表示轉(zhuǎn)流層負(fù)責(zé)記錄每個(gè)處理管道的地址,以及管道數(shù)據(jù)交換以及日志的緩存。數(shù)據(jù)交換層主要負(fù)責(zé)相互隔離的2個(gè)管道的數(shù)據(jù)交換。管道工作層主要負(fù)責(zé)用戶邏輯的處理部分,數(shù)據(jù)的合并處理,數(shù)據(jù)的流出處理。日志層主要用于管道崩潰后,根據(jù)日志進(jìn)行數(shù)據(jù)的恢復(fù),以及管道m(xù)assage的記錄。回調(diào)層,主要用于任務(wù)處理完畢或者管道合并后的結(jié)果輸出。
2.1? 服務(wù)表示轉(zhuǎn)流層
服務(wù)表示轉(zhuǎn)流層主要分為服務(wù)注冊(cè)中心、管道全局中心。服務(wù)注冊(cè)中心[3]在管道服務(wù)框架中使用,全局管道空間實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Key-value數(shù)據(jù)庫(kù),當(dāng)然可以使用ETCD[4]或者Redis[5]來(lái)作為服務(wù)注冊(cè)中心的載體。
服務(wù)注冊(cè)中心的作用主要是為了維護(hù)每個(gè)管道或者管道組的正常運(yùn)行,維護(hù)每個(gè)管道或者管道組的信息,實(shí)際上在使用中會(huì)把多個(gè)管道合并為一個(gè)集合,包括管道集合所在的IP端口,以及它擁有的管道ID。并且每個(gè)管道集合必須定時(shí)的重新上報(bào)自己的情況,否則過(guò)期后,服務(wù)注冊(cè)中心會(huì)刪除這個(gè)管道集合的信息。
管道全局中心的主要作用是用于在不同分區(qū)中的管道交換數(shù)據(jù)時(shí),會(huì)先在管道全局中心中緩存數(shù)據(jù),發(fā)送管道先緩存數(shù)據(jù),然后告知目標(biāo)管道,目標(biāo)管道激活后直接通過(guò)管道交換通道獲取到對(duì)應(yīng)的數(shù)據(jù),流入管道。值得注意的是,為了保證在發(fā)生網(wǎng)絡(luò)分區(qū)時(shí),框架的數(shù)據(jù)恢復(fù)能力,管道對(duì)全局空間并不會(huì)直接操作,而是需要通過(guò)管道交換通道進(jìn)行。
2.2? 數(shù)據(jù)交換層
數(shù)據(jù)交換層主要由多個(gè)管道交換通道組成,一般來(lái)說(shuō)管道交換通道的數(shù)目與管道集合的數(shù)目相等,即一個(gè)集合一個(gè)管道交換通道,管道交換通道主要用于解決數(shù)據(jù)一致性問(wèn)題;數(shù)據(jù)通道解決事務(wù)一致性問(wèn)題,保證管道推送的數(shù)據(jù)一定被日志記錄以及被上傳到管道全局中心中。然后去通知接收管道,同時(shí)管道交換通道還負(fù)責(zé)負(fù)載均衡的實(shí)現(xiàn),如果管道在流出數(shù)據(jù)時(shí)沒(méi)有指定目標(biāo)管道的唯一標(biāo)識(shí)ID,而是指定了管道服務(wù)ID,那么數(shù)據(jù)交換層會(huì)盡可能均衡的推送數(shù)據(jù)到管道集合中管道服務(wù)ID相同的分組。同時(shí)管道交換通道還支持動(dòng)態(tài)均衡[4]策略,管道交換通道會(huì)跟蹤每一個(gè)管道分配的拉取時(shí)間,對(duì)于分配拉取管道拉取時(shí)間慢的管道集合地址更新更小的權(quán)重,根據(jù)權(quán)重來(lái)進(jìn)行負(fù)載均衡。
交換層代碼為:
func (cr*ConsulResolver) resolveService(ctxcontext.Context) (string, connect.CertURI, error) {
health :=cr.Client.Health()
svcs, _, err :=health.Connect(cr.Name, "", true, cr.query Options(ctx))
iferr!=nil {
return"", nil, err
}
iflen(svcs) <1 {
return"", nil, fmt.Errorf("no healthy instances found")
}
// Services are not shuffled by HTTP API, pick one at (pseudo) random.
idx :=0
iflen(svcs) >1 {
idx=rand.Intn(len(svcs))
}
returncr.resolveServiceEntry(svcs[idx])
}
func (cr*ConsulResolver) resolveQuery(ctxcontext.Context) (string, connect.CertURI, error) {
resp, _, err :=cr.Client.PreparedQuery().Execute(cr.Name, cr.queryOptions(ctx))
iferr!=nil {
return"", nil, err
}
svcs :=resp.Nodes
iflen(svcs) <1 {
return"", nil, fmt.Errorf("no healthy instances found")
}
// Services are not shuffled by HTTP API, pick one at (pseudo) random.
idx :=0
iflen(svcs) >1 {
idx=rand.Intn(len(svcs))
}
returncr.resolveServiceEntry(&svcs[idx])
}
2.3? 管道工作層
管道工作層作為管道服務(wù)框架中實(shí)際的工作角色,用戶將給每個(gè)不同的管道定義不同的工作任務(wù),同時(shí)定義管道的服務(wù)ID或者叫作任務(wù)ID,定義管道的流動(dòng)條件,定義管道的推送條件,定義管道的合并條件。如在計(jì)算階乘和的任務(wù)中,我們可以分解出計(jì)算階乘和求和的子任務(wù),這2個(gè)任務(wù)會(huì)被定義到2個(gè)不同的管道中并且有自己的任務(wù)ID,在這個(gè)任務(wù)中我們可以開啟多個(gè)計(jì)算階乘的管道,一個(gè)組合的管道,并且指示計(jì)算階乘的管道的流出是組合管道,在組合管道中會(huì)對(duì)階乘管道的求出結(jié)果做合并,最后輸出到流出器中等待回調(diào)得到最終的結(jié)果。管道的基本工作流出如圖2所示。
管道工作層代碼為:
typePolicystruct {
ID? ? ? ? ? ? ? ? ? ? string? ? ? ? ? ? ? ? ?`hcl:"id"`
Revision? ? ? ? ? ? ? uint64? ? ? ? ? ? ? ? ?`hcl:"revision"`
ACL? ? ? ? ? ? ? ? ? ?string? ? ? ? ? ? ? ? ?`hcl:"acl,expand"`
Agents? ? ? ? ? ? ? ? []*AgentPolicy? ? ? ? ?`hcl:"agent,expand"`
AgentPrefixes? ? ? ? ?[]*AgentPolicy? ? ? ? ?`hcl:"agent_prefix,expand"`
Keys? ? ? ? ? ? ? ? ? []*KeyPolicy? ? ? ? ? ?`hcl:"key,expand"`
KeyPrefixes? ? ? ? ? ?[]*KeyPolicy? ? ? ? ? ?`hcl:"key_prefix,expand"`
Nodes? ? ? ? ? ? ? ? ?[]*NodePolicy? ? ? ? ? `hcl:"node,expand"`
NodePrefixes? ? ? ? ? []*NodePolicy? ? ? ? ? `hcl:"node_prefix,expand"`
Services? ? ? ? ? ? ? []*ServicePolicy? ? ? ?`hcl:"service,expand"`
ServicePrefixes? ? ? ?[]*ServicePolicy? ? ? ?`hcl:"service_prefix,expand"`
Sessions? ? ? ? ? ? ? []*SessionPolicy? ? ? ?`hcl:"session,expand"`
SessionPrefixes? ? ? ?[]*SessionPolicy? ? ? ?`hcl:"session_prefix,expand"`
Events? ? ? ? ? ? ? ? []*EventPolicy? ? ? ? ?`hcl:"event,expand"`
EventPrefixes? ? ? ? ?[]*EventPolicy? ? ? ? ?`hcl:"event_prefix,expand"`
PreparedQueries? ? ? ?[]*PreparedQueryPolicy`hcl:"query,expand"`
PreparedQueryPrefixes[]*PreparedQueryPolicy`hcl:"query_prefix,expand"`
Keyring? ? ? ? ? ? ? ?string? ? ? ? ? ? ? ? ?`hcl:"keyring"`
Operator? ? ? ? ? ? ? string? ? ? ? ? ? ? ? ?`hcl:"operator"`
}
2.4? 管道工作層調(diào)度模型
在管道服務(wù)框架的實(shí)現(xiàn)中,管道的工作使用GMP模型,模型分為M、P、G三個(gè)角色,分別代表POSIX Threads,Processor和Go Pipeline。P可以理解為執(zhí)行上下文,也就是context,P負(fù)責(zé)完成對(duì)G和M的調(diào)度,我們可以把M理解為操作系統(tǒng)資源的抽象,是真正的執(zhí)行體;把G理解為要執(zhí)行任務(wù)的抽象,是執(zhí)行代碼和數(shù)據(jù)的集合。P用執(zhí)行體M來(lái)執(zhí)行G,并且維護(hù)了一個(gè)隊(duì)列來(lái)存放可執(zhí)行的G,當(dāng)前G執(zhí)行結(jié)束,M就空閑了下來(lái),P就可以從隊(duì)列的頂部取出下一個(gè)G在M上繼續(xù)執(zhí)行。
當(dāng)M去執(zhí)行該系統(tǒng)調(diào)用時(shí)線程會(huì)阻塞并被操作系統(tǒng)掛起,這個(gè)時(shí)候P會(huì)把當(dāng)前的G留在原來(lái)的M中處理,然后從隊(duì)列里取出下一個(gè)G并創(chuàng)建一個(gè)新的M對(duì)象來(lái)執(zhí)行它。被的G-M對(duì)完成系統(tǒng)調(diào)用變成可執(zhí)行狀態(tài)時(shí),又會(huì)在合適的時(shí)機(jī)被重新調(diào)度執(zhí)行。如圖3所示。
圖中,長(zhǎng)矩形為全局可用資源,包括全局隊(duì)列、操作系統(tǒng);圓角長(zhǎng)矩形為局部可用資源,圖中為局部隊(duì)列;圓形為虛擬工作角色,即工作管道;正方形為具有調(diào)度功能的角色,圖中為P(虛擬調(diào)度器)以及CPU(調(diào)度器);三角形為實(shí)際工作內(nèi)核線程;虛線標(biāo)記部分標(biāo)識(shí)其為虛擬整體,圖中相對(duì)于整個(gè)系統(tǒng)CPU為一個(gè)整體工作,實(shí)際上CPU獨(dú)立互不干涉。
使用以上模型,可以使管道用更小的開銷異步處理計(jì)算密集型以及IO密集型的任務(wù),相對(duì)來(lái)說(shuō),更適合處理IO任務(wù),并且解決了分布式管道設(shè)計(jì)模式中用戶的管道選擇問(wèn)題,降低了管道設(shè)計(jì)模式的任務(wù)分層時(shí)的選擇復(fù)雜度,使得用戶只需要關(guān)注如何拆分任務(wù)。
2.5? 回調(diào)層
回調(diào)層主要為結(jié)果的輸出,用戶最終使用回調(diào)層提供的接口,如圖1中的流出器獲取到管道處理完畢的數(shù)據(jù)。值得注意的是,為了解決管道資源的占用問(wèn)題,管道使用回調(diào)層流出數(shù)據(jù)后會(huì)立刻釋放當(dāng)前的資源,認(rèn)為該任務(wù)集合的本次任務(wù)已經(jīng)完成。
2.6? 日志層
日志層主要分為異常日志和恢復(fù)日志:
(1)異常日志。異常日志主要用于記錄POSIX Threads這里可以理解為操作系統(tǒng)回調(diào)的錯(cuò)誤日志,以及框架用戶在GOPipeline中手動(dòng)定義,并且被拋出觸發(fā)的錯(cuò)誤,異常任務(wù)可以對(duì)框架的執(zhí)行情況進(jìn)行簡(jiǎn)要的分析,使得框架具有更好的錯(cuò)誤檢測(cè),中斷分析能力[6]。
(2)恢復(fù)日志。在管道設(shè)計(jì)模式中全局管道空間儲(chǔ)存每一次管道執(zhí)行任務(wù)后得到的中間態(tài)數(shù)據(jù),并且管道全局中心中的數(shù)據(jù)保存在內(nèi)存中,一旦發(fā)生宕機(jī)或者進(jìn)程意外終止等問(wèn)題,管道全局中心中的數(shù)據(jù)會(huì)全部損失,對(duì)應(yīng)的管道任務(wù)需要重新執(zhí)行。為解決上述問(wèn)題管道設(shè)計(jì)模式參考Redis的持久化策略[5]引入恢復(fù)日志來(lái)解決框架的容災(zāi)問(wèn)題?;謴?fù)日志的工作主要分為以下3個(gè)過(guò)程。
1)管道全局中心會(huì)在計(jì)算壓力較小的時(shí)候,對(duì)管道全局中心的數(shù)據(jù)進(jìn)行磁盤持久化,被稱為備份,并且在恢復(fù)日志中打下一個(gè)版本標(biāo)記。
2)管道交換通道每產(chǎn)生一次中間態(tài)數(shù)據(jù),優(yōu)先記錄操作到恢復(fù)日志中,保證管道全局中心以及恢復(fù)日志的原子性,一致性[7]。
3)一旦發(fā)生導(dǎo)致進(jìn)程崩潰的問(wèn)題,在管道服務(wù)框架重新啟動(dòng)時(shí)優(yōu)先從最新的備份中恢復(fù)數(shù)據(jù)到管道全局中心中,根據(jù)備份的版本號(hào),到恢復(fù)日志中逐步對(duì)該版本號(hào)以后的操作進(jìn)行恢復(fù)。
以下為日志層代碼:
funcSetup(config*Config, uicli.Ui) (*logutils.LevelFilter, *GatedWriter, *LogWriter, io.Writer, bool) {
// The gated writer buffers logs at startup and holds until it's flushed.
logGate :=&GatedWriter{
Writer: &cli.UiWriter{Ui: ui},
}
// Set up syslog if it's enabled.
varsyslogio.Writer
ifconfig.EnableSyslog {
retries :=12
delay :=5*time.Second
fori :=0; i<=retries; i++ {
...
// Create a log writer, and wrap a logOutput around it
logWriter :=NewLogWriter(512)
writers := []io.Writer{logFilter, logWriter}
varlogOutputio.Writer
ifsyslog!=nil {
writers=append(writers, syslog)
}
}
3? 管道服務(wù)框架設(shè)計(jì)與驗(yàn)證
3.1? 任務(wù)說(shuō)明
我們對(duì)巨潮網(wǎng)上市公司2020年期間的報(bào)告數(shù)據(jù)進(jìn)行爬取,同時(shí)使用樸素貝葉斯算法進(jìn)行主題抽取,獲取年報(bào)中財(cái)務(wù)分析部分的報(bào)表內(nèi)容,并且對(duì)每個(gè)提取到數(shù)據(jù)進(jìn)行儲(chǔ)存分析。
3.2? 任務(wù)瓶頸分析
通過(guò)對(duì)巨潮網(wǎng)爬蟲的年報(bào)進(jìn)行估計(jì),全國(guó)上市公司共3 869家其中深圳股市有2 241家,上海股市有1 628家,平均每個(gè)年度的報(bào)告數(shù)據(jù)為900條目,平均年報(bào)大小為1 350 kB,粗略估計(jì)總IO任務(wù)讀寫大小為4.05 TB,可以確定該任務(wù)為高IO復(fù)雜度任務(wù)。在本次實(shí)驗(yàn)任務(wù)中,假設(shè)樸素貝葉斯模型的訓(xùn)練過(guò)程已經(jīng)完成,來(lái)分析樸素貝葉斯模型的計(jì)算壓力。利用式(1)對(duì)離散數(shù)據(jù)進(jìn)行簡(jiǎn)單化計(jì)算:
P(X|Ci)=P(xk|Cj)? ? ? ? ? ? ? ? ?(1)
式(1)中,P(X|Ci)為Ci文本屬于X的概率,P(xk|Cj)為Cj中包含詞條xk的概率。
樸素貝葉斯分類器[8],分類的設(shè)計(jì)復(fù)雜度大概為O(C× D),其中C為類別,D為特征數(shù)。在本次二分類問(wèn)題中時(shí)間復(fù)雜度為O(2D)屬于線性時(shí)間復(fù)雜度,由于在本次實(shí)驗(yàn)任務(wù)中,需要對(duì)每個(gè)上市公司的報(bào)告進(jìn)行分段輸入樸素貝葉斯分類器中進(jìn)行分類,根據(jù)對(duì)巨潮網(wǎng)的財(cái)報(bào)分析平均需要對(duì)3 000 byte(每個(gè)段落的大小)進(jìn)行分割計(jì)算,所以本次任務(wù)也屬于高計(jì)算密集型任務(wù)。
綜上所述,本次設(shè)計(jì)目標(biāo)為高IO高計(jì)算密集型任務(wù),任務(wù)主要瓶頸為IO瓶頸,其次為計(jì)算瓶頸,最后為任務(wù)調(diào)度開銷。
3.3? 任務(wù)分層情況與管道設(shè)計(jì)
對(duì)于以上任務(wù),在管道服務(wù)框架中,按照復(fù)雜度分離,可以概括為以下幾個(gè)任務(wù):數(shù)據(jù)請(qǐng)求返回、原始數(shù)據(jù)保存、數(shù)據(jù)分割、樸素貝葉斯分類、報(bào)表數(shù)據(jù)統(tǒng)計(jì)。其中IO任務(wù)主要集中在數(shù)據(jù)請(qǐng)求,保存部分即數(shù)據(jù)采集部分。計(jì)算密集型任務(wù)主要存在于數(shù)據(jù)分割、樸素貝葉斯分類部分。報(bào)表數(shù)據(jù)產(chǎn)生的IO相對(duì)于數(shù)據(jù)采集部分IO的開銷極小,在本文中不做統(tǒng)計(jì)。經(jīng)過(guò)以上分析可以建立以下管道任務(wù)模型,如圖4所示。
在圖4中,我們共定義了3個(gè)管道集合,管道集合的定義,可以把一類有較高瓶頸任務(wù)的組合在一起,如數(shù)據(jù)請(qǐng)求管道,數(shù)據(jù)采集保存集合代表了高IO任務(wù),數(shù)據(jù)分段解析集合,數(shù)據(jù)分類集合都是一個(gè)高CPU密集型集合任務(wù)。在分布式管道設(shè)計(jì)模式理論中,將每個(gè)管道分離出來(lái)會(huì)有更好的處理能力,更小的粒度,但是在我們進(jìn)行分機(jī)部署工作時(shí),就需要指定大量的管道部署,這是一個(gè)非常復(fù)雜的過(guò)程,同時(shí)也會(huì)出現(xiàn)數(shù)據(jù)交換管道過(guò)多出現(xiàn)管道全局中心搶占問(wèn)題。在本次設(shè)計(jì)的服務(wù)框架中,使用管道集合的方式集中的管理一些管道,這樣的做法會(huì)導(dǎo)致管道的高解耦合性有一定影響,但是在一定程度上我們可以在用戶對(duì)管道集合的設(shè)計(jì)部分分離出可能出現(xiàn)高耦合的任務(wù)。如圖4中分離出了文章分類管道,使得數(shù)據(jù)的處理和我們的分類任務(wù)分離使用不同的數(shù)據(jù)交換管道,來(lái)獲取更高的性能和錯(cuò)誤恢復(fù)能力。
3.4? 對(duì)比實(shí)驗(yàn)
本次實(shí)驗(yàn)只采用完整任務(wù)的1/1 000的工作量,并且使用上述的管道服務(wù)框架,以及GoCollaborate框架,一個(gè)提供分布式服務(wù)管理搭建的輕量級(jí)通用框架,可以輕松地用它進(jìn)行編程,構(gòu)建擴(kuò)展,以及創(chuàng)建自己的高性能分布式服務(wù)。使用上述的2個(gè)框架同時(shí)實(shí)現(xiàn)對(duì)平安銀行、東航物流、中科軟3個(gè)企業(yè)在2020的年報(bào)分析,并且對(duì)2個(gè)不同框架做,丟包率、內(nèi)存使用情況、CPU負(fù)載情況、單位請(qǐng)求QPS做了比較研究。
3.5? 實(shí)驗(yàn)結(jié)果
在實(shí)驗(yàn)過(guò)程中使用pprof[9],一種Go自帶的工具,可以做CPU和內(nèi)存的profiling。對(duì)2個(gè)不同框架對(duì)任務(wù)實(shí)現(xiàn)的內(nèi)存以及CPU負(fù)載情況進(jìn)行查看,結(jié)果如圖5所示。
圖5中可以觀察到管道服務(wù)框架的內(nèi)存和CPU的占用率都要大于GoCollaborate框架,換言之,管道服務(wù)框架的開銷較大,這很有可能是管道服務(wù)框架的管道全局中心中,產(chǎn)生大量的數(shù)據(jù)交換,以及恢復(fù)日志的處理導(dǎo)致的。同時(shí)在6、7、8時(shí)間點(diǎn),管道服務(wù)框架的CPU占用明顯下降經(jīng)過(guò)分析,在6、7、8時(shí)間點(diǎn),全局管道交換中出現(xiàn)高IO占用,管道服務(wù)框架,優(yōu)先處理數(shù)據(jù)保存流出管道的拉取推送任務(wù),而GoCollaborate框架是平衡的,在高IO任務(wù)到來(lái)時(shí),它必須分配更多的CPU資源去管理IO任務(wù)。
在本次實(shí)驗(yàn)中,為檢查每秒請(qǐng)求數(shù)(querypersecond,QPS)情況,使用自搭建Web服務(wù)器,只實(shí)現(xiàn)讀取接口,并對(duì)在單位時(shí)間內(nèi),本次實(shí)驗(yàn)采用1分鐘作為運(yùn)行時(shí)間,使用Gin框架[10](一個(gè)go語(yǔ)言實(shí)現(xiàn)的高性能web框架)對(duì)日志分析獲取單位時(shí)間內(nèi)的QPS量。
QPS=req((請(qǐng)求數(shù))/sec(秒)),在本次實(shí)驗(yàn)中單位時(shí)間一定,QPS=req/60。得到QPS數(shù)據(jù)如表1所示。
在單純QPS的檢測(cè)中,框架性能相差不大,對(duì)于單純的高IO任務(wù),管道服務(wù)框架和GoCollaborate框架在宏觀上來(lái)看都是平衡的,那么QPS的瓶頸在gin服務(wù)器中。
在本次實(shí)驗(yàn)中丟包率以及總工作時(shí)間,使用系統(tǒng)運(yùn)行日志進(jìn)行分析,即在框架層面,每次發(fā)生數(shù)據(jù)傳輸丟失重新傳輸時(shí),或者發(fā)生日志恢復(fù)時(shí),認(rèn)為發(fā)生丟包。在本次使用中的丟包率指的是在應(yīng)用層發(fā)生重發(fā)的概率,忽略傳輸層的情況。使用W=重發(fā)數(shù)據(jù)包/發(fā)送數(shù)據(jù)包,來(lái)計(jì)算丟包率,結(jié)果如表2所示。
管道服務(wù)框架的丟包率要遠(yuǎn)大于GoCollaborate框架,經(jīng)過(guò)分析,這是由于管道服務(wù)框架在交互數(shù)據(jù)需要經(jīng)過(guò),管道、管道交換通道、管道全局中心、管道交換通道、管道,5個(gè)過(guò)程,GoCollaborate框架只需要從一個(gè)服務(wù)到另外一個(gè)服務(wù),2個(gè)過(guò)程,并且GoCollaborate框架保證數(shù)據(jù)安全在傳輸層中解決,管道服務(wù)框架的數(shù)據(jù)安全保障在應(yīng)用層中處理。在表現(xiàn)上管道服務(wù)框架的數(shù)據(jù)傳輸安全性較差,但在應(yīng)用層中進(jìn)行安全保證,使得在發(fā)生災(zāi)禍時(shí),管道服務(wù)框架有更好的容災(zāi)能力。
4? 結(jié)? 論
特定的計(jì)算環(huán)境產(chǎn)生的不同特征的問(wèn)題,本文的實(shí)驗(yàn)過(guò)程在不同特點(diǎn),不同計(jì)算性能要求情況下的處理能力往往不同。在真實(shí)應(yīng)用環(huán)境下的性能可能達(dá)不到預(yù)期要求,隨著更多實(shí)際計(jì)算任務(wù)場(chǎng)景的出現(xiàn),分布式管道如何更高效地解決計(jì)算機(jī)資源的處理、調(diào)度仍需更深層次的研究。通過(guò)結(jié)合本文研究的不足之處,須在以下方面進(jìn)行相應(yīng)改進(jìn):
(1)在連續(xù)性任務(wù)中,若中間某一類數(shù)據(jù)管道全部斷開連接,則數(shù)據(jù)將被迫留在管道全局中心中,可能導(dǎo)致全局管道空間數(shù)據(jù)溢出。對(duì)于此問(wèn)題可以在全局管道空間中對(duì)每個(gè)集合管道的推送添加緩存最大值,同時(shí)在管道交換通道中添加緩存和通知機(jī)制,嘗試重新喚醒斷開連接的管道,最終解決管道全局中心數(shù)據(jù)溢出問(wèn)題。
(2)在數(shù)據(jù)推送過(guò)程中,數(shù)據(jù)在原管道—原管道交換通道—全局管道空間—目標(biāo)管道交換通道—目標(biāo)管道轉(zhuǎn)移。在此過(guò)程中,由于網(wǎng)絡(luò)交換的次數(shù)較多數(shù)據(jù)更易丟失。對(duì)于此問(wèn)題,可以在數(shù)據(jù)交換頻繁,單次計(jì)算量較小的部分定義一個(gè)快速管道(實(shí)現(xiàn)管道于管道之間直接通信,犧牲容災(zāi)性),提高數(shù)據(jù)處理效率,降低框架丟包率。
(3)全局管道空間備份的時(shí)機(jī)。全局管道空間使用定時(shí)器對(duì)數(shù)據(jù)進(jìn)行定期備份,且對(duì)數(shù)據(jù)加鎖防止其在保存過(guò)程中被篡改。在系統(tǒng)在處理高負(fù)載任務(wù)時(shí)若全局管道空間進(jìn)行備份加鎖,使得管道交換通道無(wú)法進(jìn)行數(shù)據(jù)傳輸,則會(huì)影響其高計(jì)算密集任務(wù)的工作,導(dǎo)致任務(wù)長(zhǎng)期阻塞等待。在此提出一種偵察機(jī)制,使得系統(tǒng)在執(zhí)行高IO任務(wù)時(shí),有更高的備份優(yōu)先級(jí),一定程度避免在進(jìn)行高CPU任務(wù)時(shí)進(jìn)行全局管道備份,將其和定時(shí)器相結(jié)合,有效提高系統(tǒng)計(jì)算能力。
參考文獻(xiàn):
[1] HU H R,F(xiàn)ANG L L,YANG C H,et al. Research on Cloud Architecture of Enterprise Distributed Business Information System Based on SOA [J].Journal of Physics:Conference Series,2020,1684(1):1-8.
[2] 徐旻洋,高承勇,周向東,等.基于微服務(wù)架構(gòu)的大型建筑設(shè)計(jì)企業(yè)生產(chǎn)業(yè)務(wù)平臺(tái)構(gòu)建 [J].土木建筑工程信息技術(shù),2019,11(3):89-95.
[3] 袁曉晨,張衛(wèi)山,高紹姝,等.基于微服務(wù)架構(gòu)的眾包圖像數(shù)據(jù)集標(biāo)注系統(tǒng) [J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2021,30(5):83-91.
[4] 鄧兆森.一種云平臺(tái)服務(wù)狀態(tài)顯示方法及相關(guān)裝置:CN1 12737882A [P].2021-04-30.
[5] DONG Y,ZHU P F,JIANG Z Y,et al. Real Time Data Distribution Technology of SCADA based on Redis [C]//Proceedings of 2016 International Conference on Computer,Mechatronics and Electronic Engineering (CMEE 2016).Beijing:DEStech Publications,2016:190-194.
[6] 賈統(tǒng),李影,吳中海.基于日志數(shù)據(jù)的分布式軟件系統(tǒng)故障診斷綜述 [J].軟件學(xué)報(bào),2020,31(7):1997-2018.
[7] 孫志龍,沙行勉,諸葛晴鳳,等.面向內(nèi)存文件系統(tǒng)的數(shù)據(jù)一致性更新機(jī)制研究 [J].計(jì)算機(jī)科學(xué),2017,44(2):222-227.
[8] 張晨躍,劉黎志,鄧開巍,等.基于MapReduce的樸素貝葉斯算法文本分類方法 [J].武漢工程大學(xué)學(xué)報(bào),2021,43(1):102-105.
[9] 向勇,湯衛(wèi)東,杜香燕,等.基于內(nèi)核跟蹤的動(dòng)態(tài)函數(shù)調(diào)用圖生成方法 [J].計(jì)算機(jī)應(yīng)用研究,2015,32(4):1095-1099.
[10] 張晶,黃小鋒.一種基于微服務(wù)的應(yīng)用框架 [J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2016,25(9):265-270.
作者簡(jiǎn)介:戴振邦(2000—),男,漢族,福建莆田人,本科在讀,研究方向:分布式、數(shù)據(jù)挖掘、集群計(jì)算;江恩杰(2000—),男,漢族,福建漳州人,本科在讀,研究方向:人工智能、模式識(shí)別、云服務(wù);劉力嘉:(2000—),男,漢族,福建漳州人,本科在讀,研究方向:虛擬化;甘江偉(2000—),男,漢族,福建永安人,本科在讀,研究方向:微電子。