李志剛 劉竹旺
[摘 要]隊列的主要目的是提供路由并保證消息的傳遞,如果發(fā)送消息時接收者不可用,消息隊列會保留消息,直到可以成功地傳遞它。消息隊列使應用程序的集成和在不可靠但節(jié)省費用的網(wǎng)絡上開發(fā)可靠的應用程序變得更加容易。本文主要探討消息隊列在分布式系統(tǒng)數(shù)據(jù)中的應用與分析。
[關鍵詞]消息隊列 分布式系統(tǒng) 數(shù)據(jù)
消息隊列是一種進程間通訊機制,本文對單機消息隊列進行了有效的擴展,使其分布在網(wǎng)絡上作為一種基礎中間件平臺為分布式計算提供服務。隨著各種計算機標準的出現(xiàn)和技術的進步,中間件技術作為軟件行業(yè)崛起的一個嶄新分支,正在全球范圍內(nèi)迅猛發(fā)展,缺少一個開放的標準是消息中間件不能被大量使用的重要障礙。中間件技術的廣泛運用是在最近10年。消息中間件是中間件范疇中發(fā)展最快的中間件類型之一。
一、消息隊列方法的基本設計
消息隊列是操作系統(tǒng)的進程之間用于通信的一種機制,兩個或多個進程間通過訪問共同的消息隊列完成消息的交換。將消息隊列的概念擴展到位于分布式環(huán)境下不同站點上應用程序間的通信,由消息隊列機制實現(xiàn)網(wǎng)絡上的可靠消息傳送,其中涉及的消息隊列有消息接收隊列、更新發(fā)送表、消息發(fā)送管理器和消息接收管理器。
當應用程序在處理數(shù)據(jù)庫修改或更新事務時,修改更新了本地服務器的數(shù)據(jù)庫中所保存的數(shù)據(jù),同時應用程序?qū)⒏滦畔⒑透滤鶊?zhí)行的SQL(StructuredQueryLanguage)語句以消息的形式寫入到更新發(fā)送表,更新發(fā)送表的內(nèi)容和本次本地服務器數(shù)據(jù)庫更新的內(nèi)容一致。根據(jù)服務器軟件的設定,當服務器發(fā)起與其他服務器的數(shù)據(jù)一致操作時,觸發(fā)消息發(fā)送管理器將更新發(fā)送表的內(nèi)容封裝成Message消息發(fā)送給其他服務器。對本地而言,若無異常,消息將送到目的地址所指示的遠端站點的消息接收隊列中。同時接送端,一個后臺消息接收管理器一直監(jiān)視著消息接收隊列。當檢測到有消息到達時,開始讀取消息,并根據(jù)讀到的消息內(nèi)容恢復成相應的SQL語句,根據(jù)SQL語句對本地數(shù)據(jù)庫執(zhí)行所描述的更新事務。如果更新成功,則處理結(jié)束,并返回“更新成功”,否則返回“更新失敗”。此時發(fā)送端的消息發(fā)送管理器一直監(jiān)視接收隊列,根據(jù)收到的消息類型進行相應的操作,若各服務器更新成功,則將該更新發(fā)送表內(nèi)容刪除,若失敗,則周期性地重發(fā)該消息。
二、分布式消息隊列操作
分布式消息隊列的寫操作就是向一個已有的消息隊列中發(fā)送數(shù)據(jù)的過程。寫消息之前,用戶進程應獲得其消息隊列描述符msqid的值,然后由msgsnd_d()系統(tǒng)調(diào)用將數(shù)據(jù)寫入由msqid值指定的消息隊列。具體過程如下:用戶進程調(diào)用msgsnd_d()時,系統(tǒng)調(diào)用msgsnd_d()首先向本地的守護進程發(fā)送“寫數(shù)據(jù)”的請求信息,在請求信息中包含msgsnd_d()調(diào)用的參數(shù)msqid、msgflg和msgp,然后等待守護進程返回應答信息,收到應答信息后把結(jié)果返回給用戶進程,若是錯誤信息,還要設置相應的錯誤信號errno。守護進程收到“寫數(shù)據(jù)”的請求后也派生出一個子進程處理。從請求信息中分離出參數(shù)msqid、msgflg和要寫入的信息,然后在key值表中查找msqid,若不存在則將錯誤信息返回給用戶進程,若存在則返回其key值表中的key值及所在節(jié)點的IP值,然后守護進程根據(jù)得到的IP來判斷消息隊列在本地還是在異地。若在本地則調(diào)用msgsnd()向本地消息隊列中寫入數(shù)據(jù)并將結(jié)果返回給用戶進程;若在異地則根據(jù)IP向相應的節(jié)點發(fā)送包括key、msgflg和要寫入信息的“寫數(shù)據(jù)”請求,在收到應答信息后將結(jié)果返回給用戶進程。
三、消息隊列在分布式系統(tǒng)數(shù)據(jù)中的應用
分布式數(shù)據(jù)庫系統(tǒng)中的每個網(wǎng)絡節(jié)點上,在數(shù)據(jù)一致性功能模塊下,都由5個功能模塊構成:發(fā)送更新消息,接收更新消息,消息發(fā)送管理,消息接收管理和更新消息處理。
1.發(fā)送更新消息
發(fā)送更新消息的功能是向整個網(wǎng)絡所有的服務器發(fā)送更新消息數(shù)據(jù),由此使其他所有的服務器根據(jù)該消息的內(nèi)容實現(xiàn)與本服務器間的數(shù)據(jù)一致。發(fā)送更新消息通過接收本地服務器所執(zhí)行的SQL語句中對服務器中數(shù)據(jù)做出了修改的語句,接收數(shù)據(jù)修改信息,并將接收的數(shù)據(jù)修改信息封裝成消息的格式,存儲在更新發(fā)送表中,在收到發(fā)送命令后,發(fā)送給其他服務器,實現(xiàn)各服務器與本服務器的數(shù)據(jù)同步。
當發(fā)送更新消息收到數(shù)據(jù)庫執(zhí)行SQL發(fā)來的數(shù)據(jù)修改信息時,先將數(shù)據(jù)修改信息封裝成消息中的數(shù)據(jù)信息格式。消息發(fā)送命令被觸發(fā)后,在消息發(fā)送管理器的控制下,將消息以組播的形式發(fā)送給其他所有在線服務的業(yè)務服務器,實現(xiàn)正常情況下的多服務器間的數(shù)據(jù)同步。
2.接收更新消息
接收更新消息的功能是實現(xiàn)接收所有數(shù)據(jù)同步信息(業(yè)務層發(fā)來的業(yè)務數(shù)據(jù)、其他服務器發(fā)來的數(shù)據(jù)同步消息),并根據(jù)收到消息的類型對數(shù)據(jù)進行相應處理。當收到的數(shù)據(jù)是業(yè)務服務器發(fā)送來的業(yè)務數(shù)據(jù)時,對數(shù)據(jù)加以解析后將解析的數(shù)據(jù)存儲到相應的緩存區(qū)域。當接收到的數(shù)據(jù)是其他服務器發(fā)來的數(shù)據(jù)同步信息時,對同步數(shù)據(jù)加以解析,解析消息中的數(shù)據(jù)信息部分,獲取一次業(yè)務的所有數(shù)據(jù)操作并對本服務器數(shù)據(jù)庫中的數(shù)據(jù)執(zhí)行相應的SQL語句,進行相應的操作,從而實現(xiàn)本服務器與消息發(fā)送端服務器之間的數(shù)據(jù)同步。從而實現(xiàn)了在正常運轉(zhuǎn)情況下的數(shù)據(jù)同步操作。
3.消息發(fā)送管理
每個服務器在執(zhí)行對數(shù)據(jù)庫中的數(shù)據(jù)進行修改操作的SQL語句后,消息發(fā)送管理模塊對更新發(fā)布表執(zhí)行插入操作,添加一條與該條SQL語句相應的消息。服務器觸發(fā)進行數(shù)據(jù)一致過程后,要求與其他服務器進行數(shù)據(jù)一致,服務器發(fā)送數(shù)據(jù)一致命令給消息發(fā)送管理模塊,消息發(fā)送管理模塊被觸發(fā)后將消息信息發(fā)送表的內(nèi)容取出封裝成用于傳送消息,并根據(jù)當前服務器的拓撲信息將消息發(fā)送給其他服務器。當消息發(fā)送管理器模塊接收到消息收管理模塊發(fā)來的重新發(fā)送請求時,將消息信息發(fā)送表中的數(shù)據(jù)重新發(fā)送給數(shù)據(jù)同步出錯的服務器。
4.更新消息處理
服務器的接收更新消息模塊收到新消息后,消息接收管理模塊要求接收更新消息模塊將該消息交給更新消息處理模塊。更新消息處理模塊接收到消息后,按照消息編碼過程的反過程解析消息。將消息中的數(shù)據(jù)信息解析為相應的SQL語句,并根據(jù)這一SQL語句對服務器的數(shù)據(jù)進行更新。如果更新成功則向發(fā)送方返回數(shù)據(jù)更新成功并將本次更新的數(shù)據(jù)寫入數(shù)據(jù)交換表,否則返回發(fā)送失敗。
參考文獻:
[1]黃姝娟,杜承烈,尤濤.中間件技術實時性能的比較[J].計算機工程,2009,35(11):32-37.
[2]徐高潮,胡亮,鞠九賓.分布式計算系統(tǒng)[M].北京:高等教育出版社,2004:23-36.
[3]勒敏,劉建輝.分布式數(shù)據(jù)庫系統(tǒng)數(shù)據(jù)一致性維護方法[J].科技廣場,2008 (3):31-33.