簡介
近年來他托,淘寶天貓“雙十一”活動影響了整個中國互聯(lián)網(wǎng)電商的發(fā)展镇辉,在“雙十一”的背后,有一系列開放平臺技術(shù)的使用來保障電商平臺的在高峰流量下正常運行。而消息中間件RocketMQ就是其中一個重要的技術(shù)习劫。RocketMQ是阿里推出的一款開源的消息中間件。其前身是MetaQ (Metamorphosis)嚼隘,它并不遵循任何規(guī)范(如JMS,AMQP等)诽里,但是參考了各種規(guī)范與同類產(chǎn)品的設(shè)計思想,但其主要借鑒的產(chǎn)品是Apache Kafka飞蛹。
就特性來說谤狡,RocketMQ主要具有以下幾個特點:
l 能夠保證嚴格的消息順序
l 提供推/拉兩種消息模式
l 高效的訂閱者水平擴展能力
l 實時的消息訂閱機制
l 億級消息堆積能力
RocketMQ經(jīng)歷了三個主要版本迭代
- Metaq(Metamorphosis) 1.x
由開源社區(qū)killme2008(莊曉丹)維護,最后一次MetaQ的更新時間為2013年卧檐。 - Metaq 2.x
于2012 年10 月份上線墓懂,在淘寶內(nèi)部被廣泛使用。 - RocketMQ 3.x
基于阿里巴巴公司內(nèi)部開源共建原則霉囚,RocketMQ項目只維護核心功能捕仔,且去除了所有其他運行時依賴,核心功能最簡化盈罐。每個產(chǎn)品的個性化需求都在RocketMQ項目之上進行深度定制榜跌。
RocketMQ目前在GitHub上的版本更新較慢,但是阿里對外提供了消息中間件的云服務(wù)盅粪,并已正式商業(yè)運行钓葫。目前來說,GitHub上的RocketMQ并沒有主備自動切換票顾,事務(wù)等方面的功能础浮。
一、RocketMQ部署架構(gòu)介紹
RocketMQ使用Name Server集群加Broker集群的方式來搭建库物。
RocketMQ需要部署Name Server(名稱服務(wù)器)霸旗,Name Server是一個幾乎無狀態(tài)節(jié)點,可集群部署戚揭,節(jié)點之間無任何信息同步诱告。
Broker(消息服務(wù)器)部署相對復(fù)雜,Broker分為Master與Slave民晒,一個Master可以對應(yīng)多個Slave精居,但是一個Slave只能對應(yīng)一個Master。
每個Broker與Name Server集群中的所有節(jié)點建立長連接潜必,定時注冊Topic信息到所有Name Server靴姿。
Producer與Name Server集群中的其中一個節(jié)點(隨機選擇)建立長連接,定期從Name Server取Topic(消息的主題磁滚,也是消息的目的地)路由信息佛吓,并向提供Topic服務(wù)的Master建立長連接宵晚,且定時向Master發(fā)送心跳。Producer完全無狀態(tài)维雇,可集群部署淤刃。
Consumer與Name Server集群中的其中一個節(jié)點(隨機選擇)建立長連接,定期從Name Server取Topic路由信息吱型,并向提供Topic服務(wù)的Master逸贾、Slave建立長連接,且定時向Master津滞、Slave發(fā)送心跳铝侵。Consumer既可以從Master訂閱消息,也可以從Slave訂閱消息触徐,訂閱規(guī)則由Broker配置決定咪鲜。
二、消息生命周期介紹
對于任意一個消息中間件來說锌介,消息都需要經(jīng)過消息生產(chǎn)->消息存儲->消息消費三個過程嗜诀。其中消息生產(chǎn)包括了Producer端的消息構(gòu)造和消息發(fā)送,消息存儲包括了Broker端的消息接收和消息落地孔祸,消息消費包括了Consumer端的消息接收和消息處理。不同消息中間件之所以功能不同发皿,性能差異較大崔慧,其主要原因就是消息生命周期中各個階段的處理方式不同。在此簡要介紹一下RocketMQ在各個階段的處理方式穴墅。
l 消息生產(chǎn)
消息的生產(chǎn)者Producer在發(fā)送消息時惶室,會從Name Server上獲取消息的目的地(Topic)在各個Broker上的狀態(tài),如果發(fā)現(xiàn)同一個Broker下的Topic有多個Queue(隊列)玄货,則會根據(jù)RoundBin算法依次向每個Queue發(fā)送消息皇钞,此外,如果發(fā)現(xiàn)多個Broker上均有相同Topic松捉,也會依照輪詢的方式依次向這些Broker發(fā)送消息夹界。
l 消息存儲
RocketMQ的消息存儲是由consume queue和commit log配合完成的。
consume queue是消息的邏輯隊列隘世,相當于字典的目錄可柿,用于指定消息在物理文件commit log中的位置。每一個queue都有一個對應(yīng)的consume queue文件丙者。consume queue中存放的是一串20字節(jié)定長的二進制數(shù)據(jù)复斥,順序?qū)戫樞蜃x。
Commit Log是消息存放的物理文件械媒,每臺Broker上的Commit Log被本機所有的queue共享目锭,不做任何區(qū)分。CommitLog中消息存儲單元長度不固定,文件順序?qū)懥『纾S機讀键俱。
簡而言之,Broker端在收到一條消息后世分,如果是消息需要落盤编振,則會在Commit Log中寫入整條消息,并在consume queue中寫入該消息的索引信息臭埋。消息被消費時踪央,則根據(jù)consume queue中的信息去Commit Log中獲取消息。RocketMQ在消息被消費后瓢阴,并不會去Commit Log中刪除消息畅蹂,而是會保存3天(可配置)而后批量刪除。
RocketMQ支持同步刷盤及異步刷盤兩種模式荣恐,同步刷盤指的是Producer將消息發(fā)送至Broker后液斜,等待消息刷入Commit Log和consume queue后才算消息發(fā)送成功,而異步刷盤則是將消息發(fā)送至Broker后叠穆,Broker將消息放入內(nèi)存則告知Producer消息發(fā)送成功少漆,而后由Broker自行將內(nèi)存中的消息批量刷入磁盤。
l 消息消費
RocketMQ消息訂閱有兩種模式硼被,一種是Push模式示损,即Broker主動向消費端推送;另外一種是Pull模式嚷硫,即消費端在需要時检访,主動到Broker拉取。但在具體實現(xiàn)時仔掸,Push和Pull模式都是采用消費端主動拉取的方式脆贵。
Consumer端每隔一段時間主動向broker發(fā)送拉消息請求,broker在收到Pull請求后起暮,如果有消息就立即返回數(shù)據(jù)卖氨,Consumer端收到返回的消息后,再回調(diào)消費者設(shè)置的Listener方法鞋怀。如果broker在收到Pull請求時双泪,消息隊列里沒有數(shù)據(jù),broker端會阻塞請求直到有數(shù)據(jù)傳遞或超時才返回密似。
與Kafka類似焙矛,Kafka中Consumer數(shù)量不能大于Partition數(shù)量,而在RocketMQ中Consumer的數(shù)量也不能大于隊列(Queue)的數(shù)量残腌,如果Consumer超過隊列數(shù)量村斟,那么多余的Consumer將不能消費消息贫导。可以簡單理解為queue與consumer的關(guān)系是多對一的關(guān)系蟆盹。
分析
我們基于公司網(wǎng)絡(luò)孩灯,搭建了RocketMQ的環(huán)境進行測試。由于RocketMQ分為同步刷盤和異步刷盤兩種模式逾滥。不同的模式對性能的影響是巨大的峰档,故我們考慮分別對同步刷盤和異步刷盤兩種模式進行測試。本次測試設(shè)置2萬條4K字節(jié)的消息為一組寨昙,測試10組(20萬條消息),然后取平均值舔哪。搭建的服務(wù)器為SuseLinux 11 SP4欢顷,4C8G。
案例一:1生產(chǎn)者發(fā)送2W條4K字節(jié)消息捉蚤,異步刷盤
TPS: 1204.964454
案例二:1生產(chǎn)者發(fā)送2W條4K字節(jié)消息抬驴,同步刷盤
TPS: 181.9604418
可以看到,同步刷盤和異步刷盤缆巧,對性能的影響幾乎是10倍計布持。
此外,在測試中發(fā)現(xiàn)盅蝗,單個生產(chǎn)者的線程數(shù)量對消息的生產(chǎn)速度也有很大的影響鳖链。
同樣的,也可以得到異步刷盤模式下TPS與線程數(shù)量的關(guān)系墩莫,可以看到,在線程數(shù)達到16個以后逞敷,再增加線程數(shù)狂秦,對TPS的提升也不大,可以判斷此時其他因素影響了TPS的提升推捐。
而對于消息的消費來說裂问,由于RocketMQ會將消息在內(nèi)存中保存一份,因此消息的消費并不受是否持久化影響牛柒。如果是及時消費堪簿,那么消息的消費速度是極快的。
案例三:1消費者消費2W條4K字節(jié)消息
TPS: 17825.31194
從性能方面來看皮壁,消息的生產(chǎn)速度低于消息的消費速度椭更,這可以基本保證不會出現(xiàn)消息堆積的場景。且如果出現(xiàn)了消息堆積蛾魄,RocketMQ由于其消息的存儲架構(gòu)虑瀑,也不會像其他MQ一樣出現(xiàn)消息堵塞的問題湿滓。
而從RocketMQ的原理及部署架構(gòu)來看,其主要適用的場景為分布式系統(tǒng)下海量消息的消峰填谷舌狗,由于其部署架構(gòu)包含了NameServer和Broker兩種形式叽奥,因此對于較小的分布式系統(tǒng)來說,搭建和運維并不方便痛侍。
建議
相比業(yè)界比較成熟的MQ來說朝氓,RocketMQ由于是阿里部分開源的產(chǎn)品,其成熟度及社區(qū)活躍度不如Kafka主届,ActiveMQ赵哲,RabbitMQ等業(yè)界主流消息中間件。但是由于RocketMQ采用Java實現(xiàn)(Kafka使用scala語言)岂膳,其主要功能的源碼可以進行二次開發(fā)進行改造誓竿。因此若公司需要掌握一門開源中間件的技術(shù),對RocketMQ進行深入研究是有價值的谈截。
綜合來看筷屡,RocketMQ有優(yōu)點也有缺點,建議:
1簸喂、對于小規(guī)模的分布式系統(tǒng)之間需要用到消息中間件的場景毙死,可以仍然采用IBM MQ或ActiveMQ等部署運維較為簡單的開源消息中間件來實現(xiàn)。
2喻鳄、對于大型的分布式系統(tǒng)扼倘,可以考慮使用RocketMQ進行數(shù)據(jù)交互,但由于RocketMQ目前的開源版本不支持主備自動切換除呵,因此在高可用方面需要進行深入的研究再菊,必要時需要進行二次開發(fā)。
3颜曾、RocketMQ就性能來說纠拔,強于ActiveMQ,就可讀性及消息交互功能來說泛豪,強于Kafka稠诲,實際業(yè)務(wù)可根據(jù)具體需要進行選型。
4诡曙、后續(xù)可繼續(xù)深入研究RocketMQ臀叙,并總結(jié)出各關(guān)鍵技術(shù)(如消息的存儲,集群設(shè)計价卤,主備復(fù)制等)和設(shè)計思路劝萤,豐富技術(shù)儲備。