閱讀194 返回首頁    go 阿裏雲 go 技術社區[雲棲]


萬億級數據洪峰下的分布式消息引擎

在首屆阿裏巴巴中間件峰會上,來自阿裏的中間件架構師,Apache RocketMQ創始人馮嘉分享了《萬億級數據洪峰下的分布式消息引擎》。他主要從阿裏消息引擎家族史、消息引擎麵臨的挑戰,未來展望三個方麵進行了分享。在分享中,他從可用性&可靠性挑戰、熔斷機製、開源HA機製改進三個方麵入手著重介紹了“雙十一”在高可用方麵麵臨的挑戰以及阿裏消息引擎在高可用方麵的優化改進。

 

以下內容根據直播視頻整理而成。

 

阿裏消息引擎的今生前世

5be363c48c463a4ee483ddde52e379db5f2b7280

上圖展示了從2007年開始阿裏消息引擎的發展。消息引擎圍繞著RocketMQ內核,在阿裏內部有三大塊:Notify解決事務消息,采用服務端push模型,用於交易核心消息分發;MetaQ用於有序消息,采用pull模型,可以解決海量消息堆積;Aliware MQ是RocketMQ商業版,支持公有雲、金融雲、私有雲、聚石塔。

5f9488554cefbbbc91672a62feb5c5074becf978

上圖展示了服務端的分層架構,整個的Server架構是對VM友好的,在容器中可以輕量化的啟動,最上層是授權和認證,codec針對協議編碼(TCP層麵),中間是限流和熔斷,下麵是緩存cache,Mix Storage可以支持混合存儲。

c8d57a705a12254a2ff19f1f37816b22b2cb23dd

Client端的分層架構也類似。不論是微服務還是RPC,都會麵臨Broker Discovery服務發現、keepAlive長連接保持、限流和熔斷。

消息引擎的主要使用場景包括異構係統互操作、異步解耦、微服務、Backbone for EDA or CEP、數據複製同步、流計算。

萬億級數據洪峰下的挑戰

caff22b5d372271e049f3399c2cf05e9e362813d

上圖展示了“雙十一”期間交易、購物車、紅包火山的情況。通過這個場景可以看出,在“雙十一”當日,麵臨兩大挑戰:可用性和可靠性。

可用性

ad4cd74271f18394426f5afc248d6e6d9cc34ff6

根據上圖公式可知,如果平均故障恢複時間是1秒的話,那麼可用性可以達到五個9,注意是一天的時間裏奧。在消息引擎中,我們希望可用性能夠做到:1.每秒支撐千萬級消息發布;2.每條消息發布最大響應時間不超過20ms;3.每條消息發布平均響應時間不超過3ms。但是,實際的場景中難免會出現慢請求的情況。針對慢請求、長尾效應,阿裏給出的解決方案是:低延遲存儲,使用預分配+內存鎖,讀寫分離,二次異步;限流、熔斷,降級,秒級隔離;多副本高可用機製,Zab、Paxos/Raft,自動/手動切換,容災演練。

c22780deecf5501e2cf6635557c92ef830f892e4

上圖描述了消息過來之後需要經曆的四大塊:首先經過Java堆,然後經過Lock(控製讀寫),然後PageCache通過刷盤策略把消息刷到Disk中。RocketMQ的整個存儲是基於PageCache的文件存儲,經過係統地分析延遲、毛刺造成的原因,可以得出內存分配與消息讀寫是整個存儲引擎需要優化的瓶頸點。

0c8f2b8eea254728e5e0b95cb1b1fc3499da6f6b

RocketMQ在使用內存過程中會碰到很多產生Latency的場景。比如在分配內存時,當內存觸及水位watermark_low,會觸發kswapd後台回收,如果分配內存的速度大於後台回收的速度,內存會逐漸減少至水位watermark_min,同時觸發直接回收。直接回收對於匿名內存非常快,但是對於Page Cache來說非常慢,因為需要把髒頁刷到磁盤上再去回收掉。另一方麵,在訪存時,如果目標內存被swap out到磁盤上,此時需要先進行內存分配,如上所述該過程可能會產生Latency,內存分配完畢後需要進行swap in將數據Load到內存當中,該過程會涉及文件IO,也會產生一定的Latency。所以,內存的延時主要來自於訪問(讀寫)的時候以及內存分配的時候。

2c1a0e5317c99718276ab614594c6d591e5039fe

整個消息隻有直達到磁盤裏才能算寫成功,可以在Lock和PageCache之間加一個Direct Memory作為緩衝,這部分內存進行池化,避免在使用內存時產生Latency。相當於消息寫到Direct Memory就會返回,整個消息的響應時間得到了極大的提升。

通過上述的優化,我們獲得的經驗包括:操作係統Page Cache Radix Tree自旋鎖,會產生幾秒的大毛刺;如果遇到壞盤,可能Block若幹分鍾,對係統產生致命影響。操作係統內存的每個Page的阻塞鎖,產生幾百毫秒小毛刺。將這些進行優化之後,寫入數據平均響應時間不超過1ms,寫入數據最大響應時間不超過20ms(Java GC暫停線程引起)。

熔斷機製

在容量保證部分,即熔斷機製。如果應用中第四塊消息服務器出現問題,則會將其隔離出來,隔離規則是:1.最多隻能隔離30%的機器;2.響應時間過長,開始隔離1分鍾;3.調用拋異常隔離1分鍾;4.如果隔離的服務器超過30%,則有部分調用會進入隔離列表中最早隔離的機器。

開源HA機製改進

cf484ece451636616139cade1c8bba4ec040615a

Controller是其中一個非常重要的組件,需要實時監控主備的節點狀態,內部保證了三機房部署。Broker啟動的時候,它會將狀態進行上報,controller則會在另外一個集群中寫下主備狀態,最後將主備狀態同步到name server上。現在,HA大部分采用同步雙寫,通過狀態機可以進行主從同步描述。剛啟動一個機器的時候,如果沒有發現別的master那麼它就是master,然後通過異步狀態對外提供服務。再來一台機器後,由於已經有了master,那麼它會作為slaver,不斷通過數據複製,從主到備,到達一定的閾值之後狀態扭轉成半同步狀態,此時主和備之間的落差變得很小很小。最終,經過一段時間變成主備全部同步的狀態。

LinuxOpenMessaging、ApacheRocketMQ展望

OpenMessaging

33b531944f344a926ef30d82abfd5a13bf6f136d

整個規範主要分為三大塊:API層、線路層、高級特性和管理。上圖列出了早期做消息規範需要涉及的內容。比如分布式事務,內部的話一直在用阿裏的MateQ和Notify,這種分布式事務是發送者分布式事務,並沒有解決發送、broker、consumer之間的分布式事務,所以在OpenMessaging中把整個的分布式事務規劃進去。負載均衡也有很多的策略,比如基於時間退遞的。分布式追蹤主要考慮Linux CNCF中的opentracing。協議橋接主要是考慮如何和現有的規範進行橋接。在整個的消息中做一些流計算算子,在消息投遞的過程中就可以把計算邏輯做進去。Benchmark主要用於把大家拉到同一起跑線做性能測試。

d223b364873122c56533e5d8cafc98f585cdfd38

上圖是整個RocketMQ的生態如圖,下麵是企業級的應用,上麵是基於大數據產生的一些新的需求。

總結來說,下一代的消息引擎主要做四個方麵的事情:電子商務,保證高並發;物聯網領域,解決在線連接處理,即長連接;大數據領域,解決吞吐問題;金融領域,最重要的高可靠,多副本。

 

最後,打個小廣告。阿裏巴巴中間件消息團隊招聘火熱進行中。我們希望在分布式、大數據、多語言架構領域有較高造詣,有追求的同學加入我們。而團隊將會提供非常有前景的發展空間,不定期地與世界頂級技術專家交流討論,相信不想提高都難。有興趣的請簡曆到我的郵箱: vongosling@apache.org。

最後更新:2017-08-13 22:27:43

  上一篇:go  實踐篇:搭建無服務器應用--函數計算+AIP網關+雲市場(提供手機號歸屬地查詢服務)
  下一篇:go  5常見的JavaScript開發錯誤避免