本發(fā)明涉及網絡通信
技術領域:
,特別涉及一種提高消息傳遞性能的集群通信系統及其方法。
背景技術:
:在現代分布式系統中,集群中多個節(jié)點之間的異步消息傳輸通常依靠消息系統進行。與原始的點對點通信不同,消息系統在整個應用系統中承擔著數據路由的職責,可以有效地對各個子系統進行解耦。遵循發(fā)布訂閱模型的消息系統一般由三個對象構成:消息發(fā)布者(producer)、消息服務器(broker)、消息訂閱者(comsumer)。消息發(fā)布者負責產生消息,并將消息發(fā)送到消息服務器,消息可以按照主題區(qū)分為不同的類別。消息訂閱者向消息服務器訂閱一個或多個感興趣的消息類別(topic),并且只接收感興趣的消息。消息服務器則負責存儲和轉發(fā)消息。所述消息系統要將消息發(fā)布端發(fā)布的消息異步地發(fā)送給消息訂閱端?,F階段市面上主要的開源消息中間件產品有kafka,rabbitmq,activemq等,目前這些主流的中間件在可擴展性、持久化、消息的高性能投遞方面具有比較明顯的缺陷,包括:在可擴展性方面,現有技術只能保證在消息服務器端的可擴展,不能完全保證消息發(fā)布端、消息訂閱端這兩個點可擴展,處理能力有限,不能完全防止單點問題,例如消息訂閱端出現單點故障,就無法從消息服務器獲取訂閱的消息進而消費消息,從而影響與之關聯的其他系統的處理。在消息的持久化方面,現有產品一般采用數據庫(database,簡稱db)方案或文件存儲方案。對于采用db存儲方案,則會使用樹數據結構b+樹作為消息索引,b+樹涉及磁盤的隨機讀寫,當消息出現海量堆積時,b+樹膨脹造成讀寫性能急劇下降。而文件存儲方案也會頻繁地進行磁盤io讀寫,成為性能瓶頸。在消息的高性能投遞方面,現有消息系統有推(push)和拉(pull)兩種消息投遞模式。push模式是消息服務器主動地把消息推送給消息訂閱者,該方式實時性比較高,但對服務器的壓力比較大。pull模式是指客戶端主動地向服務器端拉取數據,該方式吞吐量大,但實時性低。這兩種投遞模型都不能滿足同時對實時性和吞吐量都有嚴格要求的應用場景。隨著云計算和互聯網規(guī)模的不斷擴大,具有高并發(fā)和海量消息流轉需求的業(yè)務場景越來越多,如果沿用傳統的消息系統,當面對爆發(fā)式增加的訪問壓力時,傳統的消息系統可能會產生消息處理緩慢、消息丟失甚至消息服務器宕機的現象。技術實現要素:針對以上技術問題,本發(fā)明提供了一種提高消息傳遞性能的集群通信系統及其方法,采用完全的分布式設計以解決現有技術中的單點問題提高了可擴展能力。同時,為了實現消息投遞的高性能,在消息存儲、io、消息負載均衡策略和消息推拉模式等方面進行了優(yōu)化。本發(fā)明一種提高消息傳遞性能的集群通信系統,包括消息發(fā)布端、包含多臺消息服務器的消息服務器集群、消息訂閱端和分布式協調服務集群;所述消息發(fā)布端和消息訂閱端通過消息服務集群連接,并通過消息服務集群傳遞消息,消息發(fā)布端、消息服務器集群和消息訂閱端都與分布式協調服務集群保持長連接;所述消息發(fā)布端按照發(fā)布消息的主題topic類別不同劃分為不同的組,用一個groupid作為該組的唯一標識;所述消息訂閱端按照定閱消息的主題topic類別不同劃分為不同的組,用一個groupid作為該組的唯一標識;所述消息發(fā)布端和消息訂閱端定時從分布式協調服務集群拉取topic路由信息并更新到本地,以獲取該向哪一臺消息服務器發(fā)布消息或拉取消息,而每臺消息服務器則定時向分布式協調服務集群發(fā)布提供存儲和轉發(fā)服務的topic和ip地址端口信息。優(yōu)選地,消息服務器集群將接收的消息按照主題分片保存在不同的消息服務器上。優(yōu)選地,為每個存儲分片消息的消息服務器增加復制集群,復制集群中的每個節(jié)點都存儲主節(jié)點的同一份數據,復制因子r表示一份數據復制保存在r個不同節(jié)點上。優(yōu)選地,所述復制集群包括一個主響應機leader和該主響應機leader的至少一個備用響應機follower,最初的主響應機leader通過用戶配置確定,當leader失效的時候,由該leader的所有follower投票選舉其中之一follower成為新的leader,接替之前失效的leader。優(yōu)選地,所述消息服務器集群將接收的消息按照主題分片保存在不同的消息服務器上,包括消息依據不同的topic保存在不同的邏輯隊列中,邏輯隊列用來指定消息在真實的物理文件中的偏移位置,指向消息在物理文件中的索引。優(yōu)選地,所述物理文件由多個文件segmentfile構成,segmentfile則是由若干個不定長的存儲單元組成的大小為1gb的文件,每個存儲單元指定了這條消息的長度和具體內容。優(yōu)選地,消息服務器集群提供的消息服務中所有的消息都是持久化的,即消息的存儲和轉發(fā)利用操作系統提供的頁緩存pagecache,如果在pagecache中沒有命中數據則再去訪問磁盤。優(yōu)選地,消息發(fā)送端,消息服務器集群,消息訂閱端兩兩之間底層數據通信采用推拉結合的長輪詢的消息投遞機制,消息服務器集群中某個節(jié)點根據實際消息的更新情況來處理消息訂閱端發(fā)送過來的消息拉取請求,即如果無最新消息,服務器就會將請求阻塞,直到有新消息需要傳遞或超時時才返回;消息訂閱端收到服務器發(fā)送回來的消息或者控制信息后調用處理函數處理完信息后,再次發(fā)送請求消息的長連接請求,繼而等待消息到達,進入下一個循環(huán)。本發(fā)明一種提高消息傳遞性能的集群通信方法,包括:消息發(fā)布端初始化要發(fā)送消息并指定其topic;消息發(fā)布端將本地的topic路由信息定時與協調子系統同步,然后通過topic路由信息確定該消息該發(fā)往哪一個消息服務器;消息服務器收到消息后,持久化到其文件系統,即首先寫入pagecache,當寫滿一定的頁數時再批量flush到磁盤;消息訂閱端訂閱topic;消息訂閱者向消息服務器拉取消息。優(yōu)選地,消息訂閱者拉取消息時進行負載均衡,即每個訂閱者消費一個topic下的個邏輯隊列,消費完成后刪除消息服務器上存儲的此條消息;n為該topic下的邏輯隊列數量,m為訂閱組中的訂閱者數量,表示向下取整運算。本發(fā)明與現有方案相比,具有以下有益效果:全局的無單點集群化可擴展的分布式設計。如果消息發(fā)布端或訂閱端一個或多個節(jié)點發(fā)生故障,可以由同一組中的其他節(jié)點繼續(xù)發(fā)送或接收消息,并不會中斷消息的處理流程。采用基于索引的分布式文件存儲方案,有效規(guī)避了現有的db和文件存儲的缺點,使得消息的讀寫效率更高。使用長輪詢pull的消息投遞方式,在保證消息的實時性的同時兼顧了吞吐量。附圖說明圖1是本發(fā)明提高消息傳遞性能的集群通信系統優(yōu)選實施例結構示意圖;圖2是本發(fā)明消息服務器內部結構圖;圖3是本發(fā)明消息通過異步復制線程在不同的存儲節(jié)點中保存示意圖;圖4是本發(fā)明基于索引的消息存儲數據結構;圖5是本發(fā)明基于長輪詢的消息投遞模型;圖6是本發(fā)明提高消息傳遞性能的集群通信方法第一優(yōu)選實施例的流程圖;圖7是在高并發(fā)連接情況下本發(fā)明與現有系統消息時延性能對比示意圖;圖8是在高并發(fā)連接情況下本發(fā)明與現有系統每秒成功處理消息數量對比示意圖。具體實施方式為了使本發(fā)明的目的、技術方案及優(yōu)點更加清楚明白,以下結合附圖對本發(fā)明實施例進一步詳細說明。本發(fā)明系統及方法實施例基于相同發(fā)明構思,為節(jié)省篇幅,兩者之間相同的技術描述分別有所側重,但兩者相應的技術描述可以相互引用。本發(fā)明實施例設計了一種提高消息傳遞性能的集群通信系統,是對現有技術中分布式消息中間件的改進,如圖1所示,是所述系統優(yōu)選施例整體架構示意圖。所述系統包括消息發(fā)布端、消息服務器集群、消息訂閱端和分布式協調服務集群。所述消息發(fā)布端和消息訂閱端通過消息服務集群連接,并通過消息服務集群傳遞消息,同時消息發(fā)布端、消息服務器集群和消息訂閱端都與分布式協調服務集群保持長連接,也即持久連接,鏈路保持tcp連接不斷開。與目前開源的主流消息中間件不同,本發(fā)明所述消息發(fā)布端和消息訂閱端不是單個獨立的節(jié)點,而是按照發(fā)布和訂閱消息的主題topic類別不同劃分為不同的組(例如,消息發(fā)布組1、消息發(fā)布組2),并且用一個groupid作為該組的唯一標識。另外,消息發(fā)布端和消息訂閱端定時從分布式協調服務集群拉取topic路由信息并更新到本地,以獲取該向哪一臺消息服務器發(fā)布消息或拉取消息,而每臺消息服務器則定時向分布式協調服務集群發(fā)布提供存儲和轉發(fā)服務的topic和ip地址端口信息。topic路由是由很多鍵值對構成的集合(一個鍵值對是指topic和存儲此topic的消息服務器節(jié)點地址的對應關系),鍵就是topic本身的內容,值是負責存儲此topic的消息服務器的ip地址(可能有多個)。當發(fā)布端發(fā)送消息時會根據topic到路由信息中查詢此消息應該發(fā)到哪個消息服務器(通過下述的負載均衡策略選擇一個消息服務器發(fā)送)消息服務器集群中包含多臺消息服務器,每臺消息服務器的消息存儲架構類似于mongdb的架構,將接收的消息按照主題分片保存在不同的消息服務器上。同時為了保證消息的高可用,防止單點問題發(fā)生,為每個存儲分片消息的消息服務器增加復制集群(復制集群采用了冗余存儲的方法保證數據安全,復制集群中的每個節(jié)點都存儲主節(jié)點的同一份數據,防止單點故障導致的數據丟失),復制因子r表示一份數據復制保存在r個不同節(jié)點上,r的取值一般由系統服務的可用級別確定,r=2時提供簡單的冗余和服務器故障保護,當r=3時則能保證在系統災難性故障情況下數據不丟失。復制集群指的是:使用多臺主機(一般為2臺)組成一個集群,這個集群中的每臺主機負責冗余存儲某個消息服務器(其實就是下述leader)的所有消息,防止這個消息服務器發(fā)生單點故障從而導致數據丟失。下面的follower其實就是屬于這個復制集群中的一臺主機(或一個節(jié)點)?;趶椭萍旱姆桨福敲淳鸵馕吨枰獙Χ鄠€備份進行調度,每個分片都有一個消息服務器作為主響應機leader,leader負責所有的讀寫操作,如果leader失效,那么將會有其他備用響應機follower來接管(成為新的leader)。follower只是單純地與leader同步消息即可。由此可見作為leader的server承載了全部的請求壓力,因此從集群的整體考慮,有多少個分片就意味著有多少個leader,系統會將leader均衡地分散在每個分區(qū)上來確保整體的性能穩(wěn)定。最初的leader是通過用戶配置確定的,當leader失效的時候,會通過raft算法,由該leader的所有follower投票選舉(隨機投給自己或其他follower),一旦某個follower的票數超過半數(如果投票結果沒有超過半數的會繼續(xù)重新投票直到出現為止),那么這個follower就會成為新的leader,接替之前失效的leader繼續(xù)向外提供服務。在圖2中,消息發(fā)布組1發(fā)布了m11、m12、m13、m14,4個消息,其中m11、m12、m14屬于topica,ma13屬于topicb;消息發(fā)布組2發(fā)布了m21,m22,m23,3個消息,其中m22屬于topica,m21和m23屬于topicb。消息依據不同的topic保存在不同的邏輯隊列中,邏輯隊列則相當于字典目錄用來指定消息在真實的物理文件中的偏移位置,同時,如圖3所示,消息會通過異步復制線程在不同的存儲節(jié)點中保存r份。業(yè)界一般認為當一份數據保存3份即可以保證數據99%不丟失,所以一般只需要復制兩份即可。為了減少系統頻繁讀取大文件對磁盤io和內存造成巨大壓力,如圖4所示,本文采用了一種索引存儲的數據結構將大文件拆分成小文件來提高持久化性能。消息按主題進行劃分存儲,每個主題下面都有多個隊列topicqueue,這個隊列其實是一個邏輯隊列(一種按照先進先出順序存儲消息的數據結構,邏輯隊列存儲的不是消息本身,而是消息在linux文件中的具體位置,相當于一個索引,),指向消息在物理文件中的索引。真正存儲消息的物理存儲結構segmentlsit是由多個文件segmentfile構成,segmentfile則是由若干個不定長的存儲單元組成的大小為1gb的文件,每個存儲單元指定了這條消息的長度和具體內容。優(yōu)選地,消息服務器集群提供的消息服務中所有的消息都是持久化的,為了盡量減少耗時io操作,充分提高系統性能,消息的存儲和轉發(fā)可以利用操作系統提供的頁緩存pagecache,如果在pagecache中沒有命中數據則再去訪問磁盤。所述消息服務是指整個消息系統對其他分布式應用提供的消息存儲和轉發(fā)的服務。所謂持久化是指將消息存儲在磁盤這類外部存儲器上,而不是保存在內存上,防止斷電造成存儲的內容消失,從而實現“持久存儲”。消息的刷盤策略(消息從內存中寫入到磁盤中的方式)分為同步刷盤和異步刷盤。同步刷盤是指producer(消息發(fā)布端中的某個節(jié)點)發(fā)送消息到broker(消息服務器集群中的某個節(jié)點)保證消息持久化到磁盤再返回。異步刷盤是指producer發(fā)送消息到broker后立馬返回,由后臺線程執(zhí)行異步刷盤操作,每刷滿一定頁數的pagecache消息才會持久化,即寫入到磁盤。在broker中使用了零拷貝技術,mmap調用將消息copy到內核緩沖區(qū),此時mmap調用返回消息在內核緩沖區(qū)的起始位置給應用程序,應用程序再通過write系統調用,將消息copy到socketbuffer,最后通過網卡發(fā)送出去,這樣做的好處是避免了數據在內核緩沖區(qū)和用戶緩沖區(qū)之間的相互copy,提高了消息接收和發(fā)送的效率。所述mmap調用是linux下的系統調用,是一種內存映射文件的方法,即將一個文件或者其它對象映射到進程的地址空間,實現文件磁盤地址和進程虛擬地址空間中一段虛擬地址的一一對映關系,通過這種方法可以有效提高io效率。上述write系統調用也是linux的一個函數。網絡io也是消息投遞性能和吞吐量的主要瓶頸之一,本文在提高系統網絡io性能方面主要做了兩方面的努力,使用了高性能的異步io框架和linux的零拷貝技術。本文在設計網絡通信層(是對消息發(fā)送端,消息服務器集群,消息訂閱端兩兩之間底層數據通信接口的封裝)時,使用了javanio框架netty,相對于傳統的同步阻塞式io,nio采用了reactor模式,可以大大提高服務器端的并發(fā)連接量,同時nio是異步的,也提高了數據的傳輸效率。在消息推送模型的設計上,針對推、拉模式的優(yōu)缺點互補的特性,并結合異步javasript和xml(asynchronousjavascriptandxm,簡稱ajax)長連接模型,本文提出了一種推拉結合的長輪詢的消息投遞機制,可用于消息發(fā)送端,消息服務器集群,消息訂閱端兩兩之間底層數據通信如圖5所示,所述推拉結合長輪詢的消息投遞機制具體的實現過程為:消息服務器集群中某個節(jié)點(消息服務器)根據實際消息的更新情況來處理消息訂閱端發(fā)送過來的消息拉取請求,即如果無最新消息,服務器就會將請求阻塞,直到有新消息需要傳遞或超時時才返回。消息訂閱端收到服務器發(fā)送回來的消息或者控制信息后調用處理函數處理完信息后,再次發(fā)送請求消息的長連接請求,繼而等待消息到達,進入下一個循環(huán)。消息服務器總是有源源不斷的消息到達,如果這時候消息訂閱端正在處理之前接收到的消息或者剛發(fā)送完請求還沒有建立連接,在這種連接暫時間斷的情況下,服務器會采取一定的保護措施,一般是將這些剛到的消息保存在本地,等到連接再次建立后,服務器會把所有保存的消息和最近更新的消息一次性推送到訂閱端。圖6是本發(fā)明提高消息傳遞性能的集群通信的方法第一優(yōu)選實施例的流程圖。如圖所示,該消息傳遞方法中主要步驟包括:1.首先消息發(fā)布端初始化要發(fā)送消息并指定其topic。2.消息發(fā)布端將本地的topic路由信息定時與協調子系統同步,然后通過topic路由信息確定該消息該發(fā)往哪一個消息服務器,這樣就實現了發(fā)送方的負載均衡。3.消息服務器收到消息后,持久化到其文件系統,即首先寫入pagecache,當寫滿一定的頁數時再批量flush到磁盤4.消息訂閱端訂閱topic,特別說明的是,此步驟與步驟1沒有先后關系,見下述實施例所述。5.消息訂閱者向消息服務器拉取消息,優(yōu)選地,消息訂閱者拉取消息時,進行負載均衡。前面介紹過,消息訂閱者可以是一個組,為了保證這個消息訂閱組里的每一個訂閱者都能夠平均地消費消息,本文采用了類似于操作系統分頁的算法。同一個topic下有n個邏輯隊列,假如訂閱組中有m個訂閱者,那么每個訂閱者會消費這個topic下的個邏輯隊列。消費完成后刪除消息服務器上存儲的此條消息。表示向下取整運算。本發(fā)明提高消息傳遞性能的集群通信的方法第二優(yōu)選實施例,具體步驟包括:1.消息訂閱端首先向分布式協調子系統發(fā)送訂閱請求,分布式協調子系統負責維護整個消息系統的路由信息,根據訂閱請求建立起topic和訂閱端之間的映射關系。2.消息發(fā)送端初始化消息并設置消息topic信息,然后向消息服務器集群發(fā)送此消息。為了實現發(fā)布消息的負載均衡,消息發(fā)布端會與分布式協調子系統保持心跳,即消息發(fā)布端與分布式協調子系統定時進行數據交互,并定時從分布式協調子系統獲取消息服務器集群中每個節(jié)點的地址路由信息,更新到本地內存,消息發(fā)布端發(fā)送消息時會輪詢地去選擇本次消息該發(fā)送到哪個消息服務器節(jié)點。3.消息服務器接收到消息以后,首先寫入pagecache,當寫滿一定的頁數時再批量flush到磁盤。消息持久化到磁盤又分為兩個具體步驟,一是消息首先寫入物理文件并返回該消息的在物理文件中的實際偏移地址,二是再把消息的實際偏移地址按照fifo的順序放入消息的邏輯隊列,邏輯隊列存儲的其實是消息在物理文件中的索引。這種索引存儲的數據結構將大文件拆分成小文件來提高了持久化性能。另外為了保證高可用,消息服務器采用master-slave的架構,每一個消息服務器會把消息數據同步到其他節(jié)點上,以防止出現單點故障造成消息丟失。4.消息訂閱端拉取消息時,需要進行負載均衡。消息訂閱者可以是一個組,這個消息訂閱組里的每一個訂閱者都能夠平均地消費消息。具體類似于操作系統分頁的算法。同一個topic下有n個邏輯隊列,假如訂閱組中有m個訂閱者,那么每個訂閱者會消費這個topic下的n/m個邏輯隊列。在確定拉取的目標服務器后消息訂閱端會采用長輪詢pull的方式去拉消息。長輪詢pull類似于ajax的長輪詢,它綜合了push和pull模型的優(yōu)點,消息服務器會根據實際消息的更新情況來處理消息訂閱端發(fā)送過來的消息拉取請求,如果無最新消息,服務器就會將請求阻塞,直到有新消息需要傳遞或超時時才返回。這種方法即保證了實時性同時又兼顧了吞吐量。5.消息訂閱端收到消息后,根據自己的消息消費邏輯消費消息,消費完成后向消息服務器發(fā)送ack,隨后消息服務器會從磁盤中刪除本條消息。以下將對本發(fā)明技術方案進行性能測試,并對比目前其他主流的開源消息中間件產品kafka、activemq,記錄測試結果,并分析測試數據以檢測本發(fā)明的消息實時性、吞吐量是否達到設計要求。由于硬件條件限制,測試所使用的是虛擬機集群搭建測試環(huán)境,采用vmware10工具虛擬4臺linux版本為centos6.5的主機。其中activemq和kafka各需要其中3臺作為broker。測試系統除了3臺主機運行broker以外,還需要多布置1臺主機運行協調服務。硬件環(huán)境如表1所示。表1硬件環(huán)境所需軟件配置如表2所示。表2軟件配置軟件配置操作系統centos6.5kafka2.10-0.10.0.0版本zookeeper3.4.8版本activemq5.8.0版本本消息系統1.0版本jrejavaruntimeenvironment6.0與本專利所對比的三個消息系統都是運行在java虛擬機上的,所以有必要統一jvm的主要參數,如下所示。jvm的主要參數:javahotspot(tm)64-bitservervm1.7.0_67-xx:useparallelgc-xms:512m-xmx:1g-xx:newsize:256m-xx:maxnewsize:512m-xx:permsize:128m-xx:maxpermsize:128m消息實時性測試:k個線程模擬k個消息發(fā)布者并發(fā)向消息服務器端發(fā)送基于不同topic的大小為1k的消息,同時由k個消息訂閱者監(jiān)聽各自訂閱的topic消息,每個線程發(fā)送50條消息,記錄每條消息從發(fā)布者發(fā)出到消息被訂閱者消費的平均延時。如圖7所示,記錄了三個消息系統在16、32、64、128、256個線程并發(fā)條件下的消息時延,可以看出本發(fā)明在高并發(fā)連接情況下的消息時延性能明顯好于kafka和activemq,原因在于設計良好的通信層、線程模型以及消息推拉模型,能最大限度的優(yōu)化并發(fā)連接。系統吞吐量測試:分別啟動16、32、64、128、256個線程并發(fā)發(fā)送消息并監(jiān)聽消息的接收,一個線程對應一個topic,每個線程循環(huán)發(fā)送50條消息,讓測試程序運行一段時間,記錄發(fā)送并接受成功的消息數量以及總運行時間,然后計算系統tps(每秒完成消息發(fā)送并接受成功的數量)。如圖8所示,在并發(fā)量比較小的時候本發(fā)明會略低于kafka的tps,但隨著并發(fā)量的提高,本發(fā)明tps會明顯上升并超過kafka。可見,本發(fā)明的消息傳輸機制在高并發(fā)訪問的情況下,每秒成功處理的消息數量要明顯高于kafka和activemq。以上所舉實施例,對本發(fā)明的目的、技術方案和優(yōu)點進行了進一步的詳細說明,所應理解的是,以上所舉實施例僅為本發(fā)明的優(yōu)選實施方式而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內對本發(fā)明所作的任何修改、等同替換、改進等,均應包含在本發(fā)明的保護范圍之內。當前第1頁12