天天看點

Apache RocketMQ背後的設計思路與最佳實踐

<b>摘要:</b>為了更好地讓開發者們更加深入了解阿裡開源,阿裡雲雲栖社群在3月1号了舉辦“阿裡開源項目最佳實踐”線上技術峰會,直播講述了目前阿裡新興和經典開源項目實戰經驗以及背後的開發思路。在本次線上技術峰會上,阿裡巴巴中間件架構師馮嘉深入淺出的為大家講述apache rocketmq背後的設計思路、典型場景、最佳實踐以及社群營運與商業化之路。

<b>演講嘉賓介紹:</b>

<b>馮嘉(花名鼬神)</b>,阿裡巴巴中間件架構師,具有豐富的分布式軟體架構、高并發網站設計、性能調優經驗,擁有多項分布式、推薦領域的專利。開源愛好者,關注分布式、雲計算、大資料領域。目前主要負責阿裡巴巴消息中間件生态輸出、mq商業化 ,apache rocketmq 聯合創始人,社群布道者,目前主要負責apache rocketmq的雲端商業化版本aliware mq。

<b>本次的分享主要圍繞了以下四個議題:</b>

一、分布式消息領域的相關産品以及技術體系

二、apache rocketmq的發展曆史、架構設計以及aliware mq能夠提供的進階特性

三、apache rocketmq作為消息引擎的典型應用場景、最佳實踐和rocketmq服務端調優的經驗

四、對于apache rocketmq 4.x消息引擎的未來展望以及rocektmq開源社群演進曆史和發展規劃

<b>一、分布式消息領域的相關産品以及技術體系</b>

Apache RocketMQ背後的設計思路與最佳實踐

下圖所示的是分布式系統相關的技術領域。作為一款消息中間件,rocketmq需要解決的技術問題其實在分布式系統領域中都有所展現。首先如果将分布式系統的領域按照分布式通信、分布式存儲、分布式計算以及分布式管理這四大部分進行劃分,其實就會發現在這四大技術棧下有很多的子技術。這裡列舉幾個簡單的例子,比如在分布式通信領域下對于網絡協定的選擇上面,像rocketmq是基于tcp的,而基于rocketmq核心的aliware mq是有基于http協定的網關,同時也提供了mqtt協定網關。除了像網絡協定的選擇之外,還會有i/o的模型,這也屬于分布式通信領域一個非常經典的問題。通常情況下會将i/o模型分成四種,第一種是所謂的boss與worker模型;還有一種是only boss模型,所謂的select線程和事件真正處理的線程都統一在boss裡面,這樣就減少了線程切換時産生的上下文開銷;第三種i/o模型就是将第一種與第二種i/o模型進行了整合,并利用了統計學原理,在某些比如像記憶體負載比較重的場景下,從模型一切換到模型二,也就成了所謂的dynamic model。第四種i/o模型其實并不常見,它在開源領域有一個與netty齊名的傳輸層架構grizzly中會使用到,叫做leader/fellow架構,leader/fellow其實是将select線程這部分的選擇權交給了worker,而在selector線程裡處理io事件。聊完了分布式計算領域再來談一談分布式存儲領域,這其實也是分布式領域最複雜,最難攻克的領域,包括結構化存儲、半結構化、非結構化存儲等。除此之外,在分布式計算領域,主要會涉及streaming計算、圖計算等相關的内容。而在分布式管理方面,也會涉及到很多子技術,包括分布式資料管理,這裡面會牽扯到資料多副本的問題,還有分布式一緻性、協調等,這些都屬于分布式管理相關領域。

Apache RocketMQ背後的設計思路與最佳實踐

大家對比前後兩幅圖就會發現,在消息領域需要解決的技術棧中的很多問題與分布式系統中的問題是存在交集的,是以可以說分布式消息領域融合了很多現代分布式系統技術中極具挑戰性的研究領域。

Apache RocketMQ背後的設計思路與最佳實踐

那麼目前在業界有哪些比較知名的消息引擎呢?如下圖所示,這裡面幾乎完全列舉了當下比較知名的消息引擎,包括zeromq、推特的distributedlog、apache旗下的老牌消息引擎activemq、amqp的預設實作rabbitmq、kafka、apache的activemq下的子項目artemis、同樣為apache的activemq的子項目的号稱下一代消息引擎的apollo、商業化的消息引擎ironmq以及實作了jms(java message service)标準的openmq,還有就是毫無疑問的今天分享的主角——apache rocketmq。

Apache RocketMQ背後的設計思路與最佳實踐

<b>二、apache rocketmq的發展曆史、架構設計以及aliware mq能夠提供的進階特性</b>

Apache RocketMQ背後的設計思路與最佳實踐

在簡單地為大家分享了分布式系統以及分布式消息系統所使用到的一些技術之後,接着為大家分享一下rocketmq的發展曆史、架構設計以及aliware mq能夠提供的進階特性。

<b>rocketmq的發展曆史</b>

下圖展現的就是阿裡巴巴消息引擎的發展曆史。在2007年的時候,淘寶實施了“五彩石”項目,“五彩石”用于将交易系統從單機變成分布式,也是在這個過程中産生了阿裡巴巴第一代消息引擎——notify。在2010年的時候,阿裡巴巴b2b部門基于activemq的5.1版本也開發了自己的一款消息引擎,稱為napoli,這款消息引擎在b2b裡面廣泛地被使用,不僅僅是在交易領域,在很多的背景異步解耦等方面也得到了廣泛的應用。在2011年的時候,業界出現了現在被很多大資料領域所推崇的kafka消息引擎,阿裡巴巴在研究了kafka的整體機制和架構設計之後,基于kafka的設計使用java進行了完全重寫并推出了metaq 1.0版本,主要是用于解決順序消息和海量堆積的問題。而在2012年,阿裡巴巴對于metaq進行了架構重組更新,開發出了metaq 2.0,這時就發現metaq原本基于kafka的架構在阿裡巴巴如此龐大的體系下很難進行水準擴充,是以在2012年的時候就開發了rocketmq 3.0版本。很多人會問到rocketmq 3.0和metaq 3.0的差別,其實這兩者是等價的版本,隻不過阿裡内部使用的稱為metaq 3.0,外部開源稱之為rocketmq 3.0。在2015年,又基于rocketmq開發了阿裡雲上的aliware mq和notify 3.0。在2016年的時候,阿裡巴巴将rocketmq的核心引擎捐贈給了apache基金會。

Apache RocketMQ背後的設計思路與最佳實踐

以上就是rocketmq的整體發展曆史,其實在阿裡巴巴内部圍繞着rocketmq核心打造了三款産品,分别是metaq、notify和aliware mq。這三者分别采用了不同的模型,metaq主要使用了拉模型,解決了順序消息和海量堆積問題;notify主要使用了推模型,解決了事務消息;而雲産品aliware mq則是提供了商業化的版本。

Apache RocketMQ背後的設計思路與最佳實踐

下圖是rocketmq在曆年雙11的整體情況,可以看出,從2012年開始,每年rocketmq在整個雙11當天的消息流轉都會有極大的提升。在2012年大約是100億的消息流轉,在2013年就接近了332億的消息流轉,2014年和2015年都增長得非常迅速,到2015年已經接近6500億消息流轉,在2016年的雙11當天整個阿裡巴巴集團線上通過rocketmq的消息流轉達則到了1.4萬億。

Apache RocketMQ背後的設計思路與最佳實踐

在為大家介紹完阿裡巴巴内部的消息流轉的體量之後,再給大家近距離圍觀一下目前apache rocketmq的情況,如下圖所示就是rocketmq的官網,歡迎大家star和fork。

Apache RocketMQ背後的設計思路與最佳實踐

下圖展示的是rocketmq商業化的雲上版本aliware mq的官方入口。

Apache RocketMQ背後的設計思路與最佳實踐

<b></b>

<b>rocketmq的整體架構設計</b>

下圖為大家清晰地展示了rocketmq的幾個元件,分别是nameserver、broker、producer和consumer。nameserver主要負責對于源資料的管理,包括了對于topic和路由資訊的管理,broker在啟動的時候會去向nameserver注冊并且定時發送心跳,producer在啟動的時候會到nameserver上去拉取topic所屬的broker具體位址,然後向具體的broker發送消息。

Apache RocketMQ背後的設計思路與最佳實踐

下圖是rocketmq的消息領域模型,主要分為message、topic、queue、offset以及group這幾部分。

Apache RocketMQ背後的設計思路與最佳實踐

下圖為rocketmq服務端的整體架構設計。首先最上層是授權和認證部分,因為rocketmq是基于tcp的自行研發的一套線路層協定,是以它需要編解碼以及序列化。再接下來可這一層是健康檢查,在健康檢查之後是流控和熔斷措施,因為再好的系統也需要流量保護,rocketmq也是一樣,為了良好的可用性,rocketmq提供了針對于不同次元的流量控制。再往下就是存儲,總體而言rocketmq服務端對于部署運維是非常友好的,目前阿裡巴巴内部也有很多系統在進行docker容器化。

Apache RocketMQ背後的設計思路與最佳實踐

下面這幅圖展示的是sdk的架構圖。毋庸置疑第一步需要做的事情是服務發現,需要去找到發消息或者收消息具體的broker以及broker上的topic,在此之外sdk還會需要做的事情就是長連接配接的保活。接下來與服務端相同,要有流量控制以及熔斷機制,另外為了保證實作高可用性,就需要提供補償機制,這種補償機制表現在發送端的retry和接收端的redelivery,也就是重投和重發。接下來,在sdk層還存在元資訊通知更新消息,比如nameserver上資料變更就需要進行通知。

Apache RocketMQ背後的設計思路與最佳實踐

下面這幅圖為大家展示了現在的阿裡巴巴内部消息引擎的部署架構圖。從圖中可以看到所謂的kernel就是rocketmq,在kernel之外還外置了像專門為物聯網提供解決方案的mqtt網關、主要解決多語言跨網絡問題的http網關、相容kafka 0.10.x協定與官方持續保持相容的kafka網關。

Apache RocketMQ背後的設計思路與最佳實踐

接下來為大家分享在aliware mq上幾個比較優秀的特性。第一個就是常見的事務消息,這裡的事務消息指的其實是資料發送者事務消息,簡單而言就是在真正地做業務邏輯之前會發送一條半消息到服務端,接下來發送者會執行本地的事務,在完成本地事務之後,如果成功就會向服務端發送一條确認資訊,這時候服務端會将之前的半消息事務狀态進行變更;如果失敗了,服務端就會不斷地回調用戶端,來保證發送端的事務一緻性。

Apache RocketMQ背後的設計思路與最佳實踐

第二個特性就是我們去年最新研發的一套基于原有多機房部署的叢集模式,利用分布式鎖和通知機制,借助controller元件,設計并實作了高可用架構。請注意,ha controller是消息引擎高可用架構中降低系統故障恢複時間的一個重要的無狀态元件,通過監聽服務狀态變更,控制狀态機狀态切換,進而完成主從狀态的一系列切換。

Apache RocketMQ背後的設計思路與最佳實踐

aliware mq的第三個特性也是非常有意思的,這個特性主要解決的是分布式鍊路追蹤問題。從下圖中可以非常清楚地看到,消息被發送到服務端,再投遞給消費者,其中還包括了失敗的次數以及一些時間點的資訊。

Apache RocketMQ背後的設計思路與最佳實踐

接下來這個進階特性也是目前在aliware mq上公測的所謂的中繼産品,這個産品目前也是在消息引擎中進行孵化的,它主要解決了跨網絡的問題。下圖中左邊是一個vpc私有網絡,右邊其實也是一個私有網絡,如果要讓這兩個私有網絡之間的應用進行網絡互通,就需要為其搭建一套relaying中繼叢集,在兩個私有網絡都能夠通路公網的前提下,通過中繼服務就可以實作兩個私有網絡的雙向通訊。這個特性可以說是極其變态的。想想看,都已經私有網絡了,還有通訊的需求,除了傳統那種複雜的硬體白名單各種配置機制外,中繼服務提供了一種靈活的軟體服務級别的細粒度控制。

Apache RocketMQ背後的設計思路與最佳實踐

<b>三、apache rocketmq作為消息引擎的典型應用場景、最佳實踐和rocketmq服務端調優的經驗</b>

Apache RocketMQ背後的設計思路與最佳實踐

在第三部分會為大家分享rocketmq作為消息引擎的典型應用場景以及最佳實踐和對于rocketmq服務端調優的經驗。這部分的分享大緻分成五個小部分:

Apache RocketMQ背後的設計思路與最佳實踐

<b>異構系統的整合</b>,這個問題比較容易了解,在原阿裡soa esb比較火的年代,很多異構系統需要進行互聯互通。

<b>應用和應用之間的松耦合</b>,這個在阿裡巴巴内部很多的同步鍊路到異步鍊路裡面,使用的非常多。

<b>事件驅動機制和複雜事件架構模型裡面的backbone</b>,底層的機制可以通過mq來玩轉。

<b>資料複制通道,</b>這個有很多比較典型的應用場景,比如模拟mysql的binlog解析,将資料的變更封裝為消息,進而複制到遠端的另外一個資料源。

<b>與流計算引擎的整合</b>,像和apache storm、spark、flink等架構進行整合,很好的服務于大資料通道。

接下來分享一下rocketmq的最佳實踐,考慮到官方已經有比較細緻的描述,這裡我會分享一些設計層面的最佳經驗,對實戰也很有幫助。從發送端和接收端來看有如下圖所示的幾個比較重要的部分。

Apache RocketMQ背後的設計思路與最佳實踐

首先對于發送端而言,需要重點關注是三個部分,一個就是發送失敗了怎麼辦,這裡就是send backoff也就是所謂的一種補償。那麼發送失敗了,怎樣進行補償呢?比如現在的機制是三次補償,需要設定每次間隔多少秒,這是就一種很好的補償機制。還有就是send reliability,也就是發送的可靠性。第三塊就是send oneway,也就是在一些大資料場景下不需要響應的情況下,可以采用send oneway的方式來迅速地提高吞吐量。

而對于消費者端而言,有幾塊也需要重點關注。一個是重複消費問題,一般情況下推薦大家通過存儲媒體探重。而如果消費失敗了或者消費速度太慢怎麼辦,有什麼樣的方式可以解決呢?一種方案就是通過并發去解決,可以通過提高并發的通道實作。第三塊就是consume batch的問題,在rocketmq裡面預設的batch是32,如果大家覺得自己消息引擎吞吐量比較低就可以提高batch,但是如果不對于服務端的限制進行調整,batch最多也就隻能達到32。

接下來分享一下阿裡巴巴内部對于rocketmq服務端性能調優的幾點經驗總結。

Apache RocketMQ背後的設計思路與最佳實踐

這幾點經驗其實都與i/o相關,首先如果要進行i/o操作,那麼就無法避免檔案句柄的調優,這個是達到一個高吞吐必備的系統調優。其次cpu的親和特性,包括線程親和cpu,記憶體親和cpu,網卡親和cpu,這裡面非常有學問。第三部分就是如何突破記憶體鎖的限制,無鎖設計是我們所推崇的。第四部分就是numa架構disable問題。這裡簡單提一下numa架構,它主要是為了解決cpu通路記憶體的響應性能問題。因為由于所有cpu都是通過一個記憶體控制器來讀取記憶體,随着cpu核不斷發展,其響應時間上的性能問題越來越明顯。于是,numa架構出現了。numa會為每個cpu核綁定一部分記憶體,每次在cpu中運作的線程會優先地去通路該cpu所對應的記憶體,而當記憶體不足的時候,會優先把cpu相對應的記憶體釋放掉。num這種預設的記憶體配置設定算法對于存儲類産品而言是存在問題的,是以建議大家對于這一部分進行disable,當然業界也有很多其他的解決方案,比如打開numa中的交叉配置設定方案。

而通過很多的線上觀察,我們發現線上程處理來自外部的請求的時候,對于記憶體的通路其實都是随機的,是以交叉配置設定方案可以使得線程對于記憶體的通路進行打散,具有一定程度上的提升。還有一部分就是pagecache flush調優,因為mq的存儲其實是一個檔案系統,那麼就避免不了與pagecache打交道,而pagecache裡面就有很多可以進行調優的,包括髒頁回寫,換頁機制等,這些都是進行調優的重點。最後一部分就是對于磁盤的i/o排程的調優,大家都知道在磁盤的i/o排程方面,linux作業系統預設為我們提供了四種方式,而通過線上的觀察以及實驗建議大家将預設的排程方式變為deadline方式,也就是最後期限排程算法,這樣就可以有效地避免i/o寫請求餓死情況的出現。

<b>四、對于apache rocketmq 4.x消息引擎的未來展望以及rocektmq開源社群演進曆史和發展規劃</b>

Apache RocketMQ背後的設計思路與最佳實踐

接下來為大家分享最後一部分,就是對于rocketmq 4.x消息引擎的未來展望。

其實目前我們也在rocketmq 社群裡面發起了這樣的一個讨論,确定了在未來rocketmq 4.x版本将會專注于電子商務、金融、物聯網以及大資料等領域。而在電子商務領域,rocketmq重點需要解決的還是高并發的問題;在金融領域重點需要解決的是消息的高可靠,也就是之前提到的分布式事務處理;在物聯網lot領域需要重點解決的一個問題就是所謂的海量終端線上也就是海量長連接配接問題;而在大資料領域,rocketmq需要重點攻克的就是海量的消息吞吐問題。

Apache RocketMQ背後的設計思路與最佳實踐

有了以上的目标之後,我們希望能夠基于統一的架構進行實作,那麼這其實很容易想到就是基于某種規範去實作四個領域裡面的程式設計api的統一。下圖中列舉出了五個業界非常有名的消息領域的規範。corba是分布式領域裡面一個非常古老的規範,corba裡面有專門針對消息的一章就是notification service,corba的協定是非常學術化的。而jms是大家都比較熟悉的,它是java領域的一套程式設計api。mqtt和amqp都是oasis組織下的協定,mqtt是面向物聯網的線路層協定,而amqp也是消息領域的一個線路層協定,很明顯,它隻是一個協定。activemq中内置了openwire,它也是一個線路層協定。上述的這些協定在我們看來都無法完全滿足對于四個領域的需求标準。

Apache RocketMQ背後的設計思路與最佳實踐

下圖列出了目前在apache官網上發起的關于open messaging規範的讨論,大家可以到官網上進行仔細閱讀。目前這套api的初稿已經完成了,我們也在與阿裡巴巴之外的像推特和雅虎這些mq廠商進行聯系,讨論并驗證這套規範能否适用于之前提到的電子商務等四個領域。

Apache RocketMQ背後的設計思路與最佳實踐

這套規範要想健康地成長,成為真正被大家所認可的規範還需要強大的後盾。那麼這個時候,linux基金會和apache基金會就會毫無疑問地走入我們的視野。rocketmq目前雖然已經捐贈給了apache基金會并作為apache的一個孵化項目,但是經過我們的深入調研,發現在apache社群發起這樣的一套規範是不太合适的,這與apache way甚至是相悖的。是以還需要linux基金會的幫助。其實在linux基金會中就會有很多開源的規範,我們也希望這套規範能夠在linux基金會下進行推進。

Apache RocketMQ背後的設計思路與最佳實踐

下圖就是為大家列出最近rocketmq 4.0在開源社群釋出後,預期在rocketmq 4.1至4.3版本中将會提供的一些特性。大家可以到官網上進行檢視,感興趣也可以參與進來。

Apache RocketMQ背後的設計思路與最佳實踐

剛才整體的介紹了rocketmq産品的大緻情況,接下來為大家介紹一下rocketmq社群的發展情況。rocketmq目前主要的開發和貢獻是在中國大陸以及包括南韓和日本在内的亞洲其他國家進行的,而我們希望rocketmq的社群的開發者和參與者能夠遍布全球。下圖是在apache中摘錄的apache的參與者在全球的分布情況,未來也希望在全球範圍内都有的開發者能夠非常積極地參與到apache rocketmq項目中來。

Apache RocketMQ背後的設計思路與最佳實踐

為了達成上面提出的目标,我們最近也在思考做這樣的幾件事情:首先會舉辦不定期的workshop和meetup,最近釋出rocketmq 4.0的時候就在國内以線下的方式舉辦了程式設計馬拉松,并且收獲了比較不錯的效果,也發現了一些願意持續跟進社群的參與者。

Apache RocketMQ背後的設計思路與最佳實踐

聊完了社群之後,還想與大家分享一下在rocketmq的孵化過程中我們對于apache基金會的初步認識。下圖中的幾個關鍵字其實非常準确地描述了apache way,那麼什麼是apache way呢?apache非常強調對于軟體進行合作開發,并且在實際上對于商業化的協定也是比較友好的,apache還強調産品需要保證高品質,講究尊重和誠實,并且強調基于技術的互動和對于規範的堅定實作的信念,最後還是将産品的安全特性作為強制要求進行考慮。

Apache RocketMQ背後的設計思路與最佳實踐

下圖就是在apache基金會對于項目進行孵化的流程。rocketmq在孵化期間也是按照這個流程一路走來的。接下來就為大家簡單介紹一下,首先要進行孵化需要選好自己的領路人,也就是champion的概念,領路人将會對于項目在apache上的孵化起到非常大的推進作用,是以如果大家有志于将自己的産品推到apache上,一個好的領路人對于項目能夠進入apache是非常重要的。這裡面的具體流程就是在社群起草一個提議,當提議通過了之後可以召集大家讨論一下提議的可行性,然後進行投票,在投票之後如果社群願意接受産品的話就會真正地開啟自己的apache孵化之旅,也就是達到了圖中最後一步的podling。

Apache RocketMQ背後的設計思路與最佳實踐

下圖中列舉了目前rocketmq在apache社群的活躍度,其實從郵件清單中很容易直覺地看出項目在社群的活躍狀态。目前在apache社群中最活躍的幾個項目就是hadoop、spark以及flink等,而且hadoop和spark的每月郵件清單的數量統計基本在400封到600封之間,目前rocketmq的郵件清單裡面每月郵件分發次數已經可以接近hadoop和spark的數字了,這裡還是要感謝大家參與到rocketmq的社群裡面。

Apache RocketMQ背後的設計思路與最佳實踐

接下來還要分享一下apache項目的組織結構。最上面是董事會,每個項目在apache裡面都有自己的pmc組織,也就是項目管理委員會,在項目管理委員會之下是committer。而每個項目之間是獨立分開的,如果你屬于這個項目的pmc并不代表還會屬于另外一個項目的pmc。而且在項目之下還會有多個子項目,正如剛才講到的apache的activemq是一個比較老牌的項目,在這個項目之下至少有4個子項目。而rocketmq目前是一個孵化的項目,如果能夠孵化成功就能夠成為頂級的項目,也就是下圖中标有pmc字樣的框框。

Apache RocketMQ背後的設計思路與最佳實踐

下圖是apache社群對于開發者和貢獻者的表彰。首先在開始時隻會是某個項目的使用者,之後可能成為貢獻者,接下來可能就會成為某個項目的committer,如果希望能夠參與這個項目未來的管理和規劃當中,會需要努力地成為pmc member,在這之上還會有foundation member,這也是最難達到境界。

Apache RocketMQ背後的設計思路與最佳實踐

下圖列出了幾篇為大家推薦的文章,如果感興趣的話可以仔細閱讀和學習。另外,大家也看到了,中間件消息團隊在做的事情有很多,非常需要一些優秀的同學加入,感興趣的可以直接聯系我。

Apache RocketMQ背後的設計思路與最佳實踐