MQ 技術產品井噴,今天來詳聊一下騰訊開源消息中間件 TubeMQ

MQ 技術產品井噴,今天來詳聊一下騰訊開源消息中間件 TubeMQ | 原力計劃

作者 | kimmking

來源 | CSDN博客,責編 | 夕顏

出品 | CSDN(ID:CSDNnews)

隨著分佈式技術的發展,MQ技術產品也出現井噴。目前除了各類常用的MQ,比如Apache的ActiveMQ,Kafka,Pulsar,RocketMQ(既是Apache,也是阿里的,頭條也是基於RocketMQ),以及RabbitMQ(美團、汽車之家大量使用)外,各大廠商都自研了自己的產品,騰訊的CMQ和TubeMQ,京東的JMQ,去哪兒的QMQ,滴滴的DDMQ(基於RocketMQ),其中不少都開源了。這裡說一下今年開源的TubeMQ。

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

騰訊開源的TubeMQ

官方介紹如下:

https://github.com/Tencent/TubeMQ/blob/master/docs/tubemq_basic_introduction_cn.md

TubeMQ是騰訊大數據在2013年開始研發的分佈式消息中間件系統(MQ),專注服務大數據場景下海量數據的高性能存儲和傳輸。經過近7年上萬億的海量數據沉澱,較之於眾多的開源MQ組件,TubeMQ在海量實踐(穩定性+性能)和低成本方面有一定的優勢,近期我們在開源TubeMQ的相關代碼及設計,更多資料正在陸續整理。

TubeMQ集群架構:

經過多年演變,TubeMQ集群分為如下5個部分:

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划
  • Portal:負責對外交互和運維操作的Portal部分,包括API和Web兩塊,API對接集群之外的管理系統,Web是在API基礎上對日常運維功能做的頁面封裝;

  • Master:負責集群控制的Control部分,該部分由1個或多個Master節點組成,Master HA通過Master節點間心跳保活、實時熱備切換完成(這是大家使用TubeMQ的Lib時需要填寫對應集群所有Master節點地址的原因),主Master負責管理整個集群的狀態、資源調度、權限檢查、元數據查詢等;

  • Broker:負責實際數據存儲的Store部分,該部分由相互之間獨立的Broker節點組成,每個Broker節點對本節點內的Topic集合進行管理,包括Topic的增、刪、改、查,Topic內的消息存儲、消費、老化、分區擴容、數據消費的offset記錄等,集群對外能力,包括Topic數目、吞吐量、容量等,通過水平擴展Broker節點來完成;

  • Client:負責數據生產和消費的Client部分,該部分我們以Lib形式對外提供,大家用得最多的是消費端,相比之前,消費端現支持Push、Pull兩種數據拉取模式,數據消費行為支持順序和過濾消費兩種。對於Pull消費模式,支持業務通過客戶端重置精確offset以支持業務extractly-once消費,同時,消費端新推出跨集群切換免重啟的BidConsumer客戶端;

  • Zookeeper:負責offset存儲的zk部分,該部分功能已弱化到僅做offset的持久化存儲,考慮到接下來的多節點副本功能該模塊暫時保留。

比較常規的分佈式MQ結構,broker功能比較重。

相比Kafka,TubeMQ的系統特點:

  1. 純Java實現語言:TubeMQ採用純Java語言開發,便於開發人員快速熟悉項目及問題處理;

  2. 引入Master協調節點:相比Kafka依賴於Zookeeper完成元數據的管理和實現HA保障不同,TubeMQ系統採用的是自管理的元數據仲裁機制方式進行,Master節點通過採用內嵌數據庫BDB完成集群內元數據的存儲、更新以及HA熱切功能,負責TubeMQ集群的運行管控和配置管理操作,對外提供接口等;通過Master節點,TubeMQ集群裡的Broker配置設置、變更及查詢實現了完整的自動化閉環管理,減輕了系統維護的複雜度;

  3. 服務器側消費負載均衡:TubeMQ採用的是服務側負載均衡的方案,而不是客戶端側操作,提升系統的管控能力同時簡化客戶端實現,更便於均衡算法升級;

  4. 系統行級鎖操作:對於Broker消息讀寫中存在中間狀態的併發操作採用行級鎖,避免重複問題;

  5. Offset管理調整:Offset由各個Broker獨自管理,ZK只作數據持久化存儲用(最初考慮完全去掉ZK依賴,考慮到後續的功能擴展就暫時保留);

  6. 消息讀取機制的改進:相比於Kafka的順序塊讀,TubeMQ採用的是消息隨機讀取模式,同時為了降低消息時延又增加了內存緩存讀寫,對於帶SSD設備的機器,增加消息滯後轉SSD消費的處理,解決消費嚴重滯後時吞吐量下降以及SSD磁盤容量小、刷盤次數有限的問題,使其滿足業務快速生產消費的需求(後面章節詳細介紹);

  7. 消費者行為管控:支持通過策略實時動態地控制系統接入的消費者行為,包括系統負載高時對特定業務的限流、暫停消費,動態調整數據拉取的頻率等;

  8. 服務分級管控:針對系統運維、業務特點、機器負載狀態的不同需求,系統支持運維通過策略來動態控制不同消費者的消費行為,比如是否有權限消費、消費時延分級保證、消費限流控制,以及數據拉取頻率控制等;

  9. 系統安全管控:根據業務不同的數據服務需要,以及系統運維安全的考慮,TubeMQ系統增加了TLS傳輸層加密管道,生產和消費服務的認證、授權,以及針對分佈式訪問控制的訪問令牌管理,滿足業務和系統運維在系統安全方面的需求;

  10. 資源利用率提升改進:相比於Kafka,TubeMQ採用連接複用模式,減少連接資源消耗;通過邏輯分區構造,減少系統對文件句柄數的佔用,通過服務器端過濾模式,減少網絡帶寬資源使用率;通過剝離對Zookeeper的使用,減少Zookeeper的強依賴及瓶頸限制;

  11. 客戶端改進:基於業務使用上的便利性以,我們簡化了客戶端邏輯,使其做到最小的功能集合,我們採用基於響應消息的接收質量統計算法來自動剔出壞的Broker節點,基於首次使用時作連接嘗試來避免大數據量發送時發送受阻(具體內容見後面章節介紹)。

這一塊基本上說清楚了特點,以及與其他MQ的一些特色的地方,其實可以猜到,一直在和kafka做對比,很多地方參與並改進了kafka,在管理能力上做了不少思考和新的實現。

TubeMQ客戶端的演進:

業務與TubeMQ接觸得最多的是消費側,怎樣更適應業務特點、更方便業務使用我們在這塊做了比較多的改進:

數據拉取模式支持Push、Pull:

  • Push客戶端:TubeMQ最初消費端版本只提供Push模式的消費,這種模式能比較快速地消費數據,減輕服務端壓力,但同時也帶來一個問題,業務使用的時候因為無法控制拉取頻率,從而容易形成數據積壓數據處理不過來;

    • 帶消費中止/繼續的Push客戶端:在收到業務反饋能否控制Push拉取動作的需求後,我們增加了resumeConsume/pauseConsume函數對,讓業務可以模擬水位線控制機制,狀態比較繁忙時調用pauseConsume函數來中止Lib後臺的數據拉取,在狀態恢復後,再調用resumeConsume通知Lib後臺繼續拉取數據;

    • Pull客戶端:我們後來版本里增加了Pull客戶端,該客戶端有別於 – Push客戶端,是由業務而非Lib主動的拉取消息並對數據處理的結果進行成功與否的確認,將數據處理的主動權留給業務。這樣處理後,雖然服務端壓力有所提升,但業務消費時積壓情況可大大緩解。


  • 數據消費行為支持順序和過濾消費:在TubeMQ設計初我們考慮是不同業務使用不同的Topic,實際運營中我們發現不少業務實際上是通過代理模式上報的數據,數據通過Topic下的文件ID或者表ID屬性來區分,業務為了消費自己的一份數據是需要全量消費該Topic下的所有數據。我們通過tid字段支持指定屬性的過濾消費模式,將數據過濾放到服務端來做,減少出流量以及客戶端的數據處理壓力。

  • 支持業務extractly-once消費:為了解決業務處理數據時需要精確回檔的需求,在客戶端版本里提供了通過客戶端重置精確offset功能,業務重啟系統時,只需通過客戶端提供待回撥時間點的消費上下文,TubeMQ即可按照指定的精確位置接續消費。該特性目前已在Flink這類實時計算框架使用,依託Flink基於checkpoint機制進行extractly-once數據處理。

推和拉是消息處理的兩個最基礎模式。推對服務器處理來說更簡單,推出去就不管了,broker變輕,但是可能單位時間推太多,導致消費端積壓,壓垮了client端系統。拉則意味著,你隨時來拿數據,broker都要保持狀態而且會產生積壓,還需要處理重試策略等。有了offset則意味著可以隨時回溯消息,但是這樣可能會導致重複,如果沒有內置的去重其實不是extractly once,而是atleast once,消息會重複。

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

其他幾個mq

滴滴的DDMQ:

https://github.com/didi/DDMQ/blob/master/README_CN.md

去哪兒網的QMQ:

https://github.com/qunarcorp/qmq

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

有意思的幾個點

TubeMQ跟 kafka,rocketmq,pulsar等主流的MQ架構上有什麼差別?

官方給出的意見是:

Kafka按照順序寫 + 順序塊讀的模式實現,單實例下性能數據很強,但隨著實例數增多,它的性能就呈現不穩定下降狀態;TubeMQ採用順序寫 + 隨機讀的模式,即使在最大限制下系統仍可以做到長期穩定的1G以上的入流量,同時,結合服務端過濾過濾消費非常順暢。

個人對這個持保留意見,大量創建topic不適合kafka的設計原則(一般我們建議單集群的topic數量在100以內,過多的小topic造成隨機讀寫,但是可以合併,然後區分和路由消息即可),同時如果改成SSD盤也可以提升吞吐和延遲,幾千個topic問題不大。而且kafka的延遲也不像上面的文檔裡對比說的250ms,我們實際使用大概在10-40ms之間。

TubeMQ看了一下,整體設計跟pulsar有點像,主要是broker和storage做了分離;消息處理模式上跟ActiveMQ到底有些許接近。

幾個有意思的地方:

1、TubeMQ不支持多副本,這樣的話單機有可能還是在極端情況下丟失數據,但多副本是目前的各種分佈式消息隊列的標配(看了一下騰訊雲上的商業版本CMQ是支持的。)

2、服務器側消費負載均衡,早期版本的kafka是這樣的,問題挺多

3、消息隨機讀,這樣需要加內存緩存和依賴SSD,挺詭異,為了併發又加了鎖,這一塊很複雜,ActiveMQ就是因為內存的處理太複雜,導致量一大,誰都用不好

4、同時支持推和拉,這一點也挺有意思,跟第一條一條有關係,要是支持推的話,服務端肯定需要有狀態

5、支持服務器端的消息過濾,現在一般的MQ都是客戶端過濾,也同理。

MQ發現到現在,一共經歷了三代,分別以ActiveMQ,Kafka/RocketMQ,Pulsar為代表,從趨勢上來看,越來越分佈式、趨向對雲原生的支持,越來越無狀態,broker越來越輕薄。

總之這個方案看起來是綜合了傳統和現在的各個MQ的一些特點,但是實現的很重。

還有個tip,TubeMQ裡的組件名稱有點亂,叫master的東西,實際上是broker,叫broker的東西,實際上是storage(在pulsar裡是bookie)。

:)

原文鏈接:

https://blog.csdn.net/KimmKing/article/details/103133789

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划
MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

今日福利

遇見陸奇

同樣作為“百萬人學 AI”的重要組成部分,2020 AIProCon 開發者萬人大會將於 7 月 3 日至 4 日通過線上直播形式,讓開發者們一站式學習瞭解當下 AI 的前沿技術研究、核心技術與應用以及企業案例的實踐經驗,同時還可以在線參加精彩多樣的開發者沙龍與編程項目。參與前瞻系列活動、在線直播互動,不僅可以與上萬名開發者們一起交流,還有機會贏取直播專屬好禮,與技術大咖連麥。

☞一站式殺手級 AI 開發平臺來襲!告別切換零散建模工具

☞北京四環堵車引發的智能交通大構想

☞拜託,別再問我什麼是堆了!

☞北京四環堵車引發的智能交通大構想

☞你公司的虛擬機還閒著?基於Jenkins和Kubernetes的持續集成測試實踐瞭解一下!

☞從Web1.0到Web3.0:詳析這些年互聯網的發展及未來方向


分享到:


相關文章: