萬億級數據洪峰下的分散式消息引擎
在首屆阿里巴巴中間件峰會上,來自阿里的中間件架構師,Apache RocketMQ創始人馮嘉分享了《萬億級數據洪峰下的分散式消息引擎》。他主要從阿里消息引擎家族史、消息引擎面臨的挑戰,未來展望三個方面進行了分享。在分享中,他從可用性&可靠性挑戰、熔斷機制、開源HA機制改進三個方面入手著重介紹了「雙十一」在高可用方面面臨的挑戰以及阿里消息引擎在高可用方面的優化改進。
以下內容根據直播視頻整理而成。
阿里消息引擎的今生前世
上圖展示了從2007年開始阿里消息引擎的發展。消息引擎圍繞著RocketMQ內核,在阿里內部有三大塊:Notify解決事務消息,採用服務端push模型,用於交易核心消息分發;MetaQ用於有序消息,採用pull模型,可以解決海量消息堆積;Aliware MQ是RocketMQ商業版,支持公有雲、金融雲、私有雲、聚石塔。
上圖展示了服務端的分層架構,整個的Server架構是對VM友好的,在容器中可以輕量化的啟動,最上層是授權和認證,codec針對協議編碼(TCP層面),中間是限流和熔斷,下面是緩存cache,Mix Storage可以支持混合存儲。
Client端的分層架構也類似。不論是微服務還是RPC,都會面臨Broker Discovery服務發現、keepAlive長連接保持、限流和熔斷。
消息引擎的主要使用場景包括異構系統互操作、非同步解耦、微服務、Backbone for EDA or CEP、數據複製同步、流計算。
萬億級數據洪峰下的挑戰
上圖展示了「雙十一」期間交易、購物車、紅包火山的情況。通過這個場景可以看出,在「雙十一」當日,面臨兩大挑戰:可用性和可靠性。
可用性
根據上圖公式可知,如果平均故障恢復時間是1秒的話,那麼可用性可以達到五個9,注意是一天的時間裡奧。在消息引擎中,我們希望可用性能夠做到:1.每秒支撐千萬級消息發布;2.每條消息發布最大響應時間不超過20ms;3.每條消息發布平均響應時間不超過3ms。但是,實際的場景中難免會出現慢請求的情況。針對慢請求、長尾效應,阿里給出的解決方案是:低延遲存儲,使用預分配+內存鎖,讀寫分離,二次非同步;限流、熔斷,降級,秒級隔離;多副本高可用機制,Zab、Paxos/Raft,自動/手動切換,容災演練。
上圖描述了消息過來之後需要經歷的四大塊:首先經過Java堆,然後經過Lock(控制讀寫),然後PageCache通過刷盤策略把消息刷到Disk中。RocketMQ的整個存儲是基於PageCache的文件存儲,經過系統地分析延遲、毛刺造成的原因,可以得出內存分配與消息讀寫是整個存儲引擎需要優化的瓶頸點。
RocketMQ在使用內存過程中會碰到很多產生Latency的場景。比如在分配內存時,當內存觸及水位watermark_low,會觸發kswapd後台回收,如果分配內存的速度大於後台回收的速度,內存會逐漸減少至水位watermark_min,同時觸發直接回收。直接回收對於匿名內存非常快,但是對於Page Cache來說非常慢,因為需要把臟頁刷到磁碟上再去回收掉。另一方面,在訪存時,如果目標內存被swap out到磁碟上,此時需要先進行內存分配,如上所述該過程可能會產生Latency,內存分配完畢後需要進行swap in將數據Load到內存當中,該過程會涉及文件IO,也會產生一定的Latency。所以,內存的延時主要來自於訪問(讀寫)的時候以及內存分配的時候。
整個消息只有直達到磁碟里才能算寫成功,可以在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機制改進
Controller是其中一個非常重要的組件,需要實時監控主備的節點狀態,內部保證了三機房部署。Broker啟動的時候,它會將狀態進行上報,controller則會在另外一個集群中寫下主備狀態,最後將主備狀態同步到name server上。現在,HA大部分採用同步雙寫,通過狀態機可以進行主從同步描述。剛啟動一個機器的時候,如果沒有發現別的master那麼它就是master,然後通過非同步狀態對外提供服務。再來一台機器後,由於已經有了master,那麼它會作為slaver,不斷通過數據複製,從主到備,到達一定的閾值之後狀態扭轉成半同步狀態,此時主和備之間的落差變得很小很小。最終,經過一段時間變成主備全部同步的狀態。
LinuxOpenMessaging、ApacheRocketMQ展望
OpenMessaging
整個規範主要分為三大塊:API層、線路層、高級特性和管理。上圖列出了早期做消息規範需要涉及的內容。比如分散式事務,內部的話一直在用阿里的MateQ和Notify,這種分散式事務是發送者分散式事務,並沒有解決發送、broker、consumer之間的分散式事務,所以在OpenMessaging中把整個的分散式事務規划進去。負載均衡也有很多的策略,比如基於時間退遞的。分散式追蹤主要考慮Linux CNCF中的opentracing。協議橋接主要是考慮如何和現有的規範進行橋接。在整個的消息中做一些流計算運算元,在消息投遞的過程中就可以把計算邏輯做進去。Benchmark主要用於把大家拉到同一起跑線做性能測試。
上圖是整個RocketMQ的生態如圖,下面是企業級的應用,上面是基於大數據產生的一些新的需求。
總結來說,下一代的消息引擎主要做四個方面的事情:電子商務,保證高並發;物聯網領域,解決在線連接處理,即長連接;大數據領域,解決吞吐問題;金融領域,最重要的高可靠,多副本。
原文鏈接:萬億級數據洪峰下的分散式消息引擎-博客-雲棲社區-阿里雲
更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎
推薦閱讀:
※除了仰望星空,數據還為你開啟了俯瞰大地的「上帝視角」
※你的舊船票能否搭上這艘巨輪?——解讀大數據產業發展規劃(2016-2020年)
※雲棲大會中你不可以錯過的技術盛宴!
※《大數據時代》讀書筆記(一):引言與P1大數據時代的思維變革
※短文本主題建模方法