腾讯企业级消息中间件CMQ技术解密
作者簡介:ziza,2012年加入騰訊,一直專注于騰訊中間件產品的建設,主導參與了騰訊消息中間件CMQ、CKafka、MQ for IoT 等項目,見證了騰訊云消息服務從0到1的整個過程。目前專注于于分布式服務開發與治理平臺TSF的建設。
大規模分布式系統的快速發展使得消息中間件已經成為系統間通信的核心手段。本文將對騰訊TEG基礎架構部中間件團隊研發的企業級消息中間件CMQ原理進行分享介紹。
背景介紹
可以使用消息隊列的場景有很多,常見的有以下幾種:
1.服務解耦:同步變異步,數據最終一致性;
2.削峰限流:類似“三峽大壩”,下游服務方被超過服務能力請求壓垮;
3.廣播訂閱:發送方不關心誰訂閱這個消息,只管發出來,拓展方便;
4.流式數據過濾:消費者通過類似SQL語句來篩選自己感興趣的數據;
5.兩階段消息:通過兩階段消息與本地數據庫事務相結合達到簡單分布式事務。
?
中間件團隊消息隊列發展歷程:
CMQ/CKafka/MQ for IoT本質上都屬于分布式消息中間件,分布式消息系統的最大特點是可擴展性。核心理念是多個節點協同工作完成單個節點無法完成的任務,不允許出現單節點故障服務不可用(RTO)和數據丟失(RPO)情況。歸根結底是解決CAP問題, CMQ作為金融級別服務要求數據高可靠強一致(CP), CKafka以大數據領域為主要服務對象,更偏重于AP,同時允許用戶通過配置在CAP之間進行權衡,本文重點對CMQ進行介紹。
核心原理介紹
整體架構介紹
架構圖
CMQ屬于典型的三層架構,支持業界主流協議,業務可以選擇HTTP/AMQP/MQTT等多種協議,適配層主要負責協議適配和路由控制,同時支撐系統水平彈性伸縮,后端Broker Set 提供消息持久化存儲、轉發以及基于消息的高階功能,例如延時消息、事務消息、死信消息等;控制Server和管控平臺負責對整個系統進行智能調度、故障處理、運營監控。
彈性伸縮:
分布式消息隊列性能和消息堆積存儲量理論上無上限,CMQ的路由控制Server 會根據存儲Set的實際負載調整消息收發路由信息并同時適配層,適配層根據收到的路由指令調整數據最終流向后端那個Set,整個過程對使用者是透明的。
數據高可靠強一致:
CMQ 利用數據多副本存儲來保證可靠性,通過Raft算法來保證副本間的數據強一致,數據生產過程大致如下:
以一個存儲Set中3個節點為例,其中只有一個Master節點可以對外接收生產數據,另外兩個節點作為Slave存在,同時Slave 會將收到的請求重定向到Master,詳細過程如下:
1.Master 負責消息的生產消費請求,收到請求后先通過Raft一致性模塊寫Raft log到本地并同步給所有Slave節點;
2.Slave 收到Master發來的Raft log持久化到本地同時返回Master 成功信息;
3.Master 收到Set中過半節點的成功信息后將請求信息提交到mq 狀態機;
4.Mq 狀態機處理請求信息后返回用戶成功;
可以看到對于生產數據CMQ會通過Raft算法確保Set中超過半數的節點已經完成存儲持久化后才返回給用戶發送成功,同時Raft 算法的選舉原理保證數據對用戶可見的強一致性,具體Raft算法不在此展開。
通過上述過程我們可以發現兩個問題:
1.上述整個流程是串行的,Raft組內順序執行上述流程,不能充分發揮節點性能;
2.相對Master節點,Slave做的事情更少,節點平時存在嚴重浪費;
為了提升QPS和機器利用率CMQ通過Multi-Raft將Set中的3個節點充分利用起來,多組Raft之前相互獨立,Master 盡量打散分布在不同節點上。
?
在研發CMQ過程中,我們將其中使用到的Raft 算法進行抽象,沉淀成可獨立使用的Raft算法庫,目前已經在部門內部多個產品中使用,逐步完善后會進一步對外開源。
上面從設計與開發角度介紹了CMQ一致性原理,但是如何驗證開發出來的CMQ是符合線性一致性的呢?為此我們參考業界知名的分布式系統完備性工具jepsen設計開發了自己的驗證系統,原理如下:
1.部署要測試的集群;
2.ControlNode執行測試程序
-
啟動集群
-
生產執行序列
-
5個client線程并發運行執行序列,同時通過Nemesis線程進行錯誤及異常注入測試,6個線程將執行過程log 記錄到history。
3. Module是根據系統行為提前定義好的正確性驗證模型,Checker結合Module分析history輸出測試報告。
?
高性能優化:
Raft 算法中存在以下兩個比較耗時的操作:
1.Master每收到一個請求都向所有Slave各發起一次網絡IO, Slave處理成功后回復Master成功。
2.Master 和Slave 還需要對收到的請求同步刷盤
對上述兩個步驟進行分解:
3.fsync_raft_log時間取決于磁盤性能,raft_log網絡傳輸時間取決于網絡RTT。由此可見這兩個值是硬件相關的,因此我們在消息個數、時間兩個維度來盡可能合并消息,做到批量發送raft_log 和批量刷盤來提高QPS。
可用性保證:
CMQ具備節點、Set、園區三級高可用保障機制,業務可根據實際需求來按需選擇。
節點可用性:
如果Set中的單個Slave 發生故障,由于此時Set滿足大多數節點可用,得益于Raft算法使得故障對業務是完全透明的;如果是Master 發生故障,此時Raft 算法會自動發起選舉,符合條件的Slave 自動提升為Master, 整個過程是秒級別的,由于存在重試邏輯,所以絕大部分情況下對業務影響也是透明的。
Set 級別可用性:
很不幸,假設一個Set中的3個節點中的兩個節點同時發生了故障,此時按照Raft算法要求的大多數節點都同意才能提交請求到MQ狀態機的原則,當前Set 是不可用的。此時CMQ通過雙Set來保障可用性,大致原理如下:
業務在申請使用消息隊列時CMQ會在兩個Set上分別建立隊列元數據,正常情況下只有一個Set 對外服務,另外一個Set standby;當一個Set 不可用時間超過一定時間,消息流會自動切換到之前Standby的Set上。為了提高Set使用率,Standby 隊列并沒有獨占Set,而是分布在不同的Set 之上。對于存留在故障Set上的還未來得及消費的數據需要故障恢復后才能正常消費。
數據中心級別可用性:
金融業務在應用層都有多中心多活的要求,防止數據中心故障后導致整個服務不可用。CMQ通過插件的方式對兩個數據中心的消息服務進行異步同步。當一個數據中心故障時任然存在少量未來的及同步的數據丟失的情況,此時需要通過log 或者對賬來恢復數據。
消息Log Trace
消息中間件日常運營中最常見的一個問題是如何證明系統沒有丟消息?為此CMQ提供了一套消息trace 系統。Agent 將每條消息的ID、生產者、消費者信息都上報到log 存儲系統,業務對于有疑問的消息可以在控制臺上直接查詢,就能看到消息的整個流轉消費情況。
開源競品對比
業界高可靠消息中間件主要以RabbitMQ為主,下面對CMQ和RabbitMQ進行分析對比。
RabbitMQ 集群鏡像模式節點間采用自研的可靠多播(Guaranteed Multicast)算法來同步數據,GM可靠多播將集群中所有節點組成一個環。Log 復制依次從 Master 向后繼節點傳播,當 Master 再次收到該請求時,發出確認消息在環中傳播,直至 Master再次收到該確認消息,表明Log 在環中所有節點同步完成。
GM算法要求Log在集群所有節點同步之后才能向客戶端返回成功;Raft算法則只要求大多數節點同步完成。Raft算法在同步路徑上比GM算法減少了近一半的等待時間。
相同條件下對CMQ 和RabbitMQ 進行性能測試,測試場景如下:三臺同樣配置的機器組成一個集群,CMQ、RabbitMQ 均配置為鏡像隊列,數據均在三臺機器上同步。 CMQ 和 RabbitMQ 都開啟生產、消費消息確認機制。測試中的生產消息大小為1KB。
| 測試環境 | 環境說明 |
| CPU | 24核 |
| 內存 | 64G |
| 磁盤 | SATA |
| 網卡 | 10G |
| Linux版本 | 2.6.32.43 |
| RabbitMQ版本 | 3.6.2 |
| Erlang版本 | 18.3 |
測試數據如下:
| QPS對比 | 僅生產 | 僅消費 | 同時生產/消費 |
| CMQ | 生產:6.8w/s | 消費:9w/s | 生產:3.6w/s |
| RabbitMQ | 生產:1.25w/s | 消費:2.6w/s | 生產:0.85w/s |
在高可靠場景中,CMQ 吞吐量優于 RabbitMQ的四倍以上。
總結
本文主要騰訊基礎架構部消息中間件發展歷程進行簡要介紹,重點對金融級消息中間件CMQ核心原理進行分享,除此之外,中間件團隊針對大數據領域常用的kafka進行優化改進推出了CKafka,在相同條件下小于4KB的情況下生產性能是開源社區的兩倍以上;針對物聯網研發的IoT Hub中的MQ引擎,完全兼容MQTT3.1協議,配合IoT Gate Way?可以輕松支持上億并發連接,歡迎大家體驗使用,也期待更多技術達人加入中間件團隊。
專題介紹
ArchSummit全球架構師峰會是InfoQ中國團隊推出的面向高端技術管理者、架構師的技術大會,參會者數量1000+。其中,出品人及演講嘉賓中高級技術專家比例占79%,90%擁有10年以上開發經驗。本次“TEGer在全球架構師峰會”專題將帶來TEG人在會上的系列主題分享。
作者簡介:ziza,2012年加入騰訊,一直專注于騰訊中間件產品的建設,主導參與了騰訊消息中間件CMQ、CKafka、MQ for IoT 等項目,見證了騰訊云消息服務從0到1的整個過程。目前專注于于分布式服務開發與治理平臺TSF的建設。
大規模分布式系統的快速發展使得消息中間件已經成為系統間通信的核心手段。本文將對騰訊TEG基礎架構部中間件團隊研發的企業級消息中間件CMQ原理進行分享介紹。
背景介紹
可以使用消息隊列的場景有很多,常見的有以下幾種:
1.服務解耦:同步變異步,數據最終一致性;
2.削峰限流:類似“三峽大壩”,下游服務方被超過服務能力請求壓垮;
3.廣播訂閱:發送方不關心誰訂閱這個消息,只管發出來,拓展方便;
4.流式數據過濾:消費者通過類似SQL語句來篩選自己感興趣的數據;
5.兩階段消息:通過兩階段消息與本地數據庫事務相結合達到簡單分布式事務。
?
中間件團隊消息隊列發展歷程:
CMQ/CKafka/MQ for IoT本質上都屬于分布式消息中間件,分布式消息系統的最大特點是可擴展性。核心理念是多個節點協同工作完成單個節點無法完成的任務,不允許出現單節點故障服務不可用(RTO)和數據丟失(RPO)情況。歸根結底是解決CAP問題, CMQ作為金融級別服務要求數據高可靠強一致(CP), CKafka以大數據領域為主要服務對象,更偏重于AP,同時允許用戶通過配置在CAP之間進行權衡,本文重點對CMQ進行介紹。
核心原理介紹
整體架構介紹
架構圖
CMQ屬于典型的三層架構,支持業界主流協議,業務可以選擇HTTP/AMQP/MQTT等多種協議,適配層主要負責協議適配和路由控制,同時支撐系統水平彈性伸縮,后端Broker Set 提供消息持久化存儲、轉發以及基于消息的高階功能,例如延時消息、事務消息、死信消息等;控制Server和管控平臺負責對整個系統進行智能調度、故障處理、運營監控。
彈性伸縮:
分布式消息隊列性能和消息堆積存儲量理論上無上限,CMQ的路由控制Server 會根據存儲Set的實際負載調整消息收發路由信息并同時適配層,適配層根據收到的路由指令調整數據最終流向后端那個Set,整個過程對使用者是透明的。
數據高可靠強一致:
CMQ 利用數據多副本存儲來保證可靠性,通過Raft算法來保證副本間的數據強一致,數據生產過程大致如下:
以一個存儲Set中3個節點為例,其中只有一個Master節點可以對外接收生產數據,另外兩個節點作為Slave存在,同時Slave 會將收到的請求重定向到Master,詳細過程如下:
1.Master 負責消息的生產消費請求,收到請求后先通過Raft一致性模塊寫Raft log到本地并同步給所有Slave節點;
2.Slave 收到Master發來的Raft log持久化到本地同時返回Master 成功信息;
3.Master 收到Set中過半節點的成功信息后將請求信息提交到mq 狀態機;
4.Mq 狀態機處理請求信息后返回用戶成功;
可以看到對于生產數據CMQ會通過Raft算法確保Set中超過半數的節點已經完成存儲持久化后才返回給用戶發送成功,同時Raft 算法的選舉原理保證數據對用戶可見的強一致性,具體Raft算法不在此展開。
通過上述過程我們可以發現兩個問題:
1.上述整個流程是串行的,Raft組內順序執行上述流程,不能充分發揮節點性能;
2.相對Master節點,Slave做的事情更少,節點平時存在嚴重浪費;
為了提升QPS和機器利用率CMQ通過Multi-Raft將Set中的3個節點充分利用起來,多組Raft之前相互獨立,Master 盡量打散分布在不同節點上。
?
在研發CMQ過程中,我們將其中使用到的Raft 算法進行抽象,沉淀成可獨立使用的Raft算法庫,目前已經在部門內部多個產品中使用,逐步完善后會進一步對外開源。
上面從設計與開發角度介紹了CMQ一致性原理,但是如何驗證開發出來的CMQ是符合線性一致性的呢?為此我們參考業界知名的分布式系統完備性工具jepsen設計開發了自己的驗證系統,原理如下:
1.部署要測試的集群;
2.ControlNode執行測試程序
-
啟動集群
-
生產執行序列
-
5個client線程并發運行執行序列,同時通過Nemesis線程進行錯誤及異常注入測試,6個線程將執行過程log 記錄到history。
3. Module是根據系統行為提前定義好的正確性驗證模型,Checker結合Module分析history輸出測試報告。
?
高性能優化:
Raft 算法中存在以下兩個比較耗時的操作:
1.Master每收到一個請求都向所有Slave各發起一次網絡IO, Slave處理成功后回復Master成功。
2.Master 和Slave 還需要對收到的請求同步刷盤
對上述兩個步驟進行分解:
3.fsync_raft_log時間取決于磁盤性能,raft_log網絡傳輸時間取決于網絡RTT。由此可見這兩個值是硬件相關的,因此我們在消息個數、時間兩個維度來盡可能合并消息,做到批量發送raft_log 和批量刷盤來提高QPS。
可用性保證:
CMQ具備節點、Set、園區三級高可用保障機制,業務可根據實際需求來按需選擇。
節點可用性:
如果Set中的單個Slave 發生故障,由于此時Set滿足大多數節點可用,得益于Raft算法使得故障對業務是完全透明的;如果是Master 發生故障,此時Raft 算法會自動發起選舉,符合條件的Slave 自動提升為Master, 整個過程是秒級別的,由于存在重試邏輯,所以絕大部分情況下對業務影響也是透明的。
Set 級別可用性:
很不幸,假設一個Set中的3個節點中的兩個節點同時發生了故障,此時按照Raft算法要求的大多數節點都同意才能提交請求到MQ狀態機的原則,當前Set 是不可用的。此時CMQ通過雙Set來保障可用性,大致原理如下:
業務在申請使用消息隊列時CMQ會在兩個Set上分別建立隊列元數據,正常情況下只有一個Set 對外服務,另外一個Set standby;當一個Set 不可用時間超過一定時間,消息流會自動切換到之前Standby的Set上。為了提高Set使用率,Standby 隊列并沒有獨占Set,而是分布在不同的Set 之上。對于存留在故障Set上的還未來得及消費的數據需要故障恢復后才能正常消費。
數據中心級別可用性:
金融業務在應用層都有多中心多活的要求,防止數據中心故障后導致整個服務不可用。CMQ通過插件的方式對兩個數據中心的消息服務進行異步同步。當一個數據中心故障時任然存在少量未來的及同步的數據丟失的情況,此時需要通過log 或者對賬來恢復數據。
消息Log Trace
消息中間件日常運營中最常見的一個問題是如何證明系統沒有丟消息?為此CMQ提供了一套消息trace 系統。Agent 將每條消息的ID、生產者、消費者信息都上報到log 存儲系統,業務對于有疑問的消息可以在控制臺上直接查詢,就能看到消息的整個流轉消費情況。
開源競品對比
業界高可靠消息中間件主要以RabbitMQ為主,下面對CMQ和RabbitMQ進行分析對比。
RabbitMQ 集群鏡像模式節點間采用自研的可靠多播(Guaranteed Multicast)算法來同步數據,GM可靠多播將集群中所有節點組成一個環。Log 復制依次從 Master 向后繼節點傳播,當 Master 再次收到該請求時,發出確認消息在環中傳播,直至 Master再次收到該確認消息,表明Log 在環中所有節點同步完成。
GM算法要求Log在集群所有節點同步之后才能向客戶端返回成功;Raft算法則只要求大多數節點同步完成。Raft算法在同步路徑上比GM算法減少了近一半的等待時間。
相同條件下對CMQ 和RabbitMQ 進行性能測試,測試場景如下:三臺同樣配置的機器組成一個集群,CMQ、RabbitMQ 均配置為鏡像隊列,數據均在三臺機器上同步。 CMQ 和 RabbitMQ 都開啟生產、消費消息確認機制。測試中的生產消息大小為1KB。
| 測試環境 | 環境說明 |
| CPU | 24核 |
| 內存 | 64G |
| 磁盤 | SATA |
| 網卡 | 10G |
| Linux版本 | 2.6.32.43 |
| RabbitMQ版本 | 3.6.2 |
| Erlang版本 | 18.3 |
測試數據如下:
| QPS對比 | 僅生產 | 僅消費 | 同時生產/消費 |
| CMQ | 生產:6.8w/s | 消費:9w/s | 生產:3.6w/s |
| RabbitMQ | 生產:1.25w/s | 消費:2.6w/s | 生產:0.85w/s |
在高可靠場景中,CMQ 吞吐量優于 RabbitMQ的四倍以上。
總結
本文主要騰訊基礎架構部消息中間件發展歷程進行簡要介紹,重點對金融級消息中間件CMQ核心原理進行分享,除此之外,中間件團隊針對大數據領域常用的kafka進行優化改進推出了CKafka,在相同條件下小于4KB的情況下生產性能是開源社區的兩倍以上;針對物聯網研發的IoT Hub中的MQ引擎,完全兼容MQTT3.1協議,配合IoT Gate Way?可以輕松支持上億并發連接,歡迎大家體驗使用,也期待更多技術達人加入中間件團隊。
專題介紹
ArchSummit全球架構師峰會是InfoQ中國團隊推出的面向高端技術管理者、架構師的技術大會,參會者數量1000+。其中,出品人及演講嘉賓中高級技術專家比例占79%,90%擁有10年以上開發經驗。本次“TEGer在全球架構師峰會”專題將帶來TEG人在會上的系列主題分享。
總結
以上是生活随笔為你收集整理的腾讯企业级消息中间件CMQ技术解密的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯移动分析系统揭密
- 下一篇: TSRC白帽子,10亿用户的守护者