<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          云原生消息流系統(tǒng) Apache RocketMQ 在騰訊云的大規(guī)模生產(chǎn)實踐

          共 16295字,需瀏覽 33分鐘

           ·

          2024-04-11 13:29

          12aba9601be6e1a407e5e36257e9acde.webp


          7cc6e06bb210aae005f4ff2a019ed7a0.webp

          導(dǎo)語

          本文將圍繞 RocketMQ 5.x 的新特性展開探討,詳細(xì)解讀其在騰訊云上的實際應(yīng)用案例,并展望未來的發(fā)展規(guī)劃。


          隨著云計算技術(shù)的日益成熟,云原生應(yīng)用已逐漸成為企業(yè)數(shù)字化轉(zhuǎn)型的核心驅(qū)動力。在這一大背景下,高效、穩(wěn)定、可擴(kuò)展的消息流系統(tǒng)顯得尤為重要。騰訊云高級開發(fā)工程師李偉先生,憑借其深厚的技術(shù)功底和豐富的實戰(zhàn)經(jīng)驗,為我們帶來了《云原生消息流系統(tǒng) Apache RocketMQ 在騰訊云的大規(guī)模生產(chǎn)實踐》的分享。本文將圍繞 RocketMQ 5.x 的新特性展開探討,詳細(xì)解讀其在騰訊云上的實際應(yīng)用案例,并展望未來的發(fā)展規(guī)劃。


          從2022年9月22日社區(qū)開始推 5.x 后,很多廠商公司都在研究或者使用 5.x 版本的 RocketMQ,在使用的過程中可以發(fā)現(xiàn),很多問題比如消費卡住的問題等就可以通過 Proxy 和 Pop 的消費來解決。


          接下來我們先從第一個主題 RocketMQ 5.x 的新特性開始。


          ede889e3cbf7c012842ec01edb8beec2.webp

          RocketMQ 5.x 的新特性


          RocketMQ 5.x 版本的新特性涵蓋了兩個方面:首先,它增強(qiáng)了那些廣受用戶關(guān)注并頻繁使用的核心功能,這些功能在實際應(yīng)用中發(fā)揮著至關(guān)重要的作用;其次,該版本還引入了一系列全新的功能特性,這些新功能將進(jìn)一步豐富 RocketMQ 的應(yīng)用場景,并提升其在消息流處理中的性能和效率。


          RocketMQ 5.x Arch


          74ecb36862c0344c01b734d49b73e384.webp


          RocketMQ 5.x 的架構(gòu)相較于 4.x 有了顯著的變化,新增了幾個關(guān)鍵組件,使得整個系統(tǒng)更加完善和高效。在部署 RocketMQ 時,我們會按照一定的順序進(jìn)行:首先是 Namesrv、控制器、Broker,然后是 Proxy,最后是生產(chǎn)消費環(huán)節(jié)。


          在生產(chǎn)消費環(huán)節(jié)中,有兩種類型的客戶端:一種是基于 TCP 的生產(chǎn)者,通常使用 Remoting 協(xié)議,這是 4.x 版本常用的客戶端;另一種則是 gRPC 客戶端,在代碼倉庫中被稱為 RocketMQ Clients。這些客戶端通過不同的協(xié)議和端口與各個組件進(jìn)行通信。


          以 Namesrv 和 Broker 之間的通信為例,當(dāng) Namesrv 啟動后,它會提供一個注冊服務(wù)。接著,在啟動 Broker 時, Broker 會根據(jù)配置的 Namesrv 地址將自己的心跳信息上報給 Namesrv。這個過程中,Broker 會使用 Remoting 協(xié)議通過9876端口將 Topic 的路由信息上報給 Namesrv。同時,如果存在控制器,Broker 還會通過19876端口向控制器上報狀態(tài)信息,以便在主從切換時進(jìn)行管理。


          在RocketMQ 4.x 中,生產(chǎn)者在發(fā)送消息前會先通過 Namesrv 獲取路由信息,然后根據(jù)這些信息將消息發(fā)送給相應(yīng)的 Broker。同樣地,消費者在消費消息時也會先從 Namesrv 獲取路由信息,然后再根據(jù)這些信息從指定的 Broker 中拉取消息進(jìn)行消費。這種機(jī)制確保了消息能夠準(zhǔn)確、高效地傳輸?shù)侥繕?biāo) Broker 并被正確消費。


          RocketMQ 5.x 與 4.x 之間的一個顯著差異在于客戶端的變化。在 5.x 版本中,客戶端采用了 gRPC 通信方式,與 4.x 的客戶端相比,它不再持有路由信息。這種改變簡化了客戶端的角色和責(zé)任。


          當(dāng) gRPC 客戶端需要發(fā)送消息時,它會直接發(fā)送一個 RPC 請求給 Proxy 組件。在這個過程中,Proxy 扮演了之前 Remoting Client 的角色。Proxy 會負(fù)責(zé)先去 Namesrv 上獲取 Topic 的路由信息,然后根據(jù)這些信息決定將消息發(fā)送給哪個 Broker。這就是 5.x 版本中消息發(fā)送的過程。


          在消費消息時,過程也是類似的。gRPC 客戶端通過發(fā)送 Pop 的 gRPC 請求給 Proxy 來請求消息。Proxy 在訪問  Broker 時使用 Pop 協(xié)議,這種協(xié)議解決了之前 Push Consumer 可能遇到的消息堆積和卡住的問題。通過 Pop 協(xié)議,消費者可以更靈活地拉取和處理消息,提高了系統(tǒng)的整體性能和可靠性。


          總的來說,RocketMQ 5.x 通過引入 gRPC 客戶端和 Proxy 組件,以及使用 Pop 協(xié)議進(jìn)行消費,實現(xiàn)了更高效、更靈活的消息處理機(jī)制。這些改進(jìn)有助于提升系統(tǒng)的可擴(kuò)展性、性能和用戶體驗。


          RocketMQ Proxy


          RocketMQ 在 5.x 版本中引入了 Proxy 組件,這是其向云原生架構(gòu)轉(zhuǎn)型的初步嘗試。Proxy 在系統(tǒng)中扮演了關(guān)鍵角色,負(fù)責(zé)處理客戶端的連接、計算路由信息以及管理消息的續(xù)期等邏輯。


          在這個新架構(gòu)下,RocketMQ 的層次結(jié)構(gòu)被劃分為三層。最上層是用戶層,負(fù)責(zé)消息的生產(chǎn)和消費。中間層是 Proxy 層,也被稱為計算層。這一層主要負(fù)責(zé)處理客戶端的連接請求,執(zhí)行路由計算,以及處理消息的續(xù)期等關(guān)鍵邏輯。最下層是存儲層,包括 Namesrv 和 Broker。Namesrv 仍然負(fù)責(zé)存儲元數(shù)據(jù),如 Topic 的路由信息和 Broker 的列表。而 Broker 則負(fù)責(zé)存儲實際的消息數(shù)據(jù)、Consumer 隊列以及索引等信息。


          通過這種層次劃分,RocketMQ 5.x 實現(xiàn)了更清晰、更靈活的系統(tǒng)架構(gòu)。Proxy 層的引入不僅提升了系統(tǒng)的可擴(kuò)展性和可維護(hù)性,還為用戶提供了更便捷、更高效的消息處理體驗。


          RocketMQ Proxy 是一個專門為 RocketMQ 協(xié)議設(shè)計的代理服務(wù)。目前,它主要支持 gRPC 客戶端的連接,并對 Remoting 協(xié)議提供了部分接口支持。通過引入計算層(即 Proxy 層),RocketMQ 在云環(huán)境中的優(yōu)勢變得更為明顯。對于服務(wù)提供者來說,計算和存儲資源可以根據(jù)實際需求進(jìn)行靈活部署,并按需計費。這種靈活性不僅提高了資源的利用率,也使得客戶能夠更經(jīng)濟(jì)高效地使用 RocketMQ 服務(wù)。


          優(yōu)勢


          RocketMQ Proxy 的優(yōu)勢非常顯著,主要表現(xiàn)在以下幾個方面:


          首先,它實現(xiàn)了存算分離。這意味著存儲和計算資源可以完全按需付費,為用戶提供了更高的靈活性和成本效益。用戶可以根據(jù)實際需求調(diào)整存儲和計算資源的配比,從而更有效地利用資源并控制成本。


          其次,RocketMQ Proxy 基于 gRPC 協(xié)議,支持多種編程語言的客戶端,如 C++、Python、Go 等。這一特性極大地簡化了不同技術(shù)棧用戶的使用體驗。在過去,Remoting 客戶端需要針對不同語言進(jìn)行單獨實現(xiàn),而社區(qū)版中 Remoting 客戶端在各語言中的功能并不對等,Java 版本最為完整和穩(wěn)定。然而,有了 Proxy 之后,各種語言的客戶端邏輯都變得非常簡單,本質(zhì)上就是一個 RPC 客戶端。這意味著一旦 RPC 客戶端穩(wěn)定下來,基本不需要改動代碼,各種語言和技術(shù)棧的用戶都可以方便地使用 RocketMQ。


          最后,RocketMQ Proxy 有助于收斂云上的復(fù)雜性。在沒有 Proxy 的情況下,用戶需要直接訪問 Namesrv 和 Broker,這涉及到復(fù)雜的網(wǎng)絡(luò)配置和隔離問題。然而,有了 Proxy 之后,用戶只需要與 Proxy 進(jìn)行網(wǎng)絡(luò)聯(lián)通,無需關(guān)心內(nèi)部細(xì)節(jié)。這種對內(nèi)復(fù)雜、對外簡單的設(shè)計理念使得客戶看起來更簡單,從而降低了整體復(fù)雜性。此外, Proxy 可以充當(dāng) HDP(Highly Distributed Platform)的角色,進(jìn)一步簡化了用戶的接入過程。

          d35058626d35b1a6e73c773e66d390f1.webp


          功能預(yù)測


          講師對 Proxy 功能未來的發(fā)展做出了一些預(yù)測:


          • 流量調(diào)度(灰度、遷移)

          首先是流量調(diào)度,包括灰度發(fā)布和遷移。講師認(rèn)為,隨著 Proxy 的功能越來越接近網(wǎng)關(guān),它可能會承擔(dān)起流量調(diào)度、灰度發(fā)布和遷移的任務(wù)。例如,在進(jìn)行跨云多活部署時,如果某個云服務(wù)出現(xiàn)故障,我們需要能夠迅速切換到其他服務(wù)。這就需要一個上層的調(diào)度組件來管理集群間的切換,而 Proxy 正是這個角色的理想選擇。


          • Namesrv、Broker 故障切換

          其次是 Namesrv 和 Broker 的故障切換。在正常的發(fā)布迭代過程中,當(dāng) Broker 出現(xiàn) Bug 并修復(fù)后,我們需要進(jìn)行灰度測試以確保新的版本沒有問題。這時,就需要進(jìn)行流量灰度,可以根據(jù)流量、用戶等因素來進(jìn)行。在 RocketMQ 中,Proxy 應(yīng)該承擔(dān)起這部分的責(zé)任,負(fù)責(zé)灰度策略的實施。


          • 統(tǒng)一鑒權(quán)

          最后是統(tǒng)一鑒權(quán)。對于 RocketMQ 內(nèi)部而言,Proxy、Namesrv 和 Broker 是緊密集成的,不需要進(jìn)行鑒權(quán)。但是,對于外部客戶來說,我們需要確保他們只能訪問到他們被授權(quán)訪問的數(shù)據(jù)。因此,未來 Proxy 可能會支持鑒權(quán)功能,以防止數(shù)據(jù)被錯誤地讀取或泄露,從而保護(hù)我們的數(shù)據(jù)安全。


          如果 Proxy 能夠支持以上三個預(yù)測的功能,那么它的角色將更接近于一個全功能的網(wǎng)關(guān),其功能將比現(xiàn)在更加強(qiáng)大和全面。


          Pop messages


          客戶可能會遇到一些問題,比如當(dāng)消費者卡住或不消費時,我們不清楚具體原因,業(yè)務(wù)也可能受到影響。在高峰期,重啟消費者又怕觸發(fā) Rebalance 導(dǎo)致消息延遲,對業(yè)務(wù)造成不良影響。這種情況下,用戶會質(zhì)疑我們能否承擔(dān)責(zé)任,處理起來非常棘手。Pop Consumer 的出現(xiàn)就是為了解決這些問題。


          在 Pop Consumer 模型中,假設(shè)有三個實例(即三個進(jìn)程)屬于相同的消費者組,每個實例都可以消費所有隊列的消息。每個實例在拉取隊列時都會進(jìn)行加法運算,然后下一個實例再拉取下一個隊列。這種模型與 Push 模型不同,Push 模型一旦分配好消費隊列,比如 Consumer3 確定消費最后兩個隊列,在 Rebalance 之前它只能消費這兩個隊列。如果它卡住了或發(fā)生其他不明狀況導(dǎo)致不消費,特別是在高峰期,重啟會帶來很大的困擾,容易造成消息延遲。這對于金融等對時間敏感的場景來說是不可接受的,因為交易慢一秒可能就意味著巨大的成本損失。


          而 Pop Consumer 模型有一個 Retry 機(jī)制,與以前的機(jī)制略有不同。當(dāng)所有 Pop 實例拉取消息時,會有一定的概率可以拉取到從事的消息(這里可能是指之前未處理成功的消息)。這個概率是通過一個隨機(jī)數(shù)算法計算出來的,以確定何時可以拉取到 Pop 的從事消息。這樣,即使某個實例卡住或不消費,其他實例仍有機(jī)會處理這些消息,從而保證了系統(tǒng)的可靠性和穩(wěn)定性。


          e074b5bc3cfb90ea0a3c315b2e07782f.webp


          Pop and ack


          c84952aa64e885339a94400dd7dc6f2e.webp


          上面這個圖展示了 Pop 消費在 Broker 端拉取消息以及進(jìn)行 ACK 確認(rèn)的整個過程。


          整個過程從 gRPC 客戶端發(fā)起請求開始,這個請求會先到達(dá)Proxy。Proxy接著會向Broker發(fā)送一個Pop請求。Broker 收到請求后的第一步是確定要拉取哪個 Queue,并將這個 Queue 鎖定。鎖定期間,其他 Pop 客戶端或?qū)嵗龑o法拉取這個 Queue 的消息。


          鎖定 Queue 后,Broker 會根據(jù)當(dāng)前的消費位點計算并決定從哪個位置開始拉取消息。確定位置后,Broker 會從 Committer 中拉取消息,并在此過程中寫入一個 Check Point。這個 Check Point 非常重要,它記錄了哪些位點的消息已經(jīng)被拉取,用于后續(xù)的 ACK 確認(rèn)。


          拉取到的消息會進(jìn)入一個不可見的時間段。這意味著,如果 Queue 被釋放了,其他客戶端或?qū)嵗诶∠r會從上一批拉取的最后一條消息的下一條開始。這是因為當(dāng)前這批消息已經(jīng)處于不可見狀態(tài)。


          寫完 Check Point 后,Broker 會釋放鎖定的 Queue,并將拉取到的消息進(jìn)行包裝后返回給 Proxy。Proxy 再通過 gRPC 將消息返回給客戶端,完成整個 Pop 過程。


          與 Push 過程相比,Pop 過程的不同之處在于它不會一直鎖定 Queue。一旦 Queue 被釋放,其他 Pop Consumer 實例就可以繼續(xù)拉取并消費這個消息。這意味著,如果之前拉取某個 Queue 的 Pop 實例停止消費,其他實例可以接管并繼續(xù)消費這個消息,避免了需要切換消費者或生產(chǎn)者的麻煩。


          ACK


          當(dāng)客戶端消費完消息后,會觸發(fā)一個 ACK 流程,這是確保消息被成功處理的關(guān)鍵步驟。ACK 主要分為兩大步驟:


          生成 Checkpoint 與消息句柄:在返回消息給客戶端時,系統(tǒng)會生成一個 Checkpoint,這是一個記錄消息處理進(jìn)度的標(biāo)記。同時,還會生成一個消息句柄,它是由 Broker Name、QID(隊列 ID)和位點信息組合而成的一個字符串。這個句柄在 ACK 時會被客戶端攜帶,用于在內(nèi)存中匹配和確認(rèn)消息。


          內(nèi)存匹配與位點持久化:當(dāng)客戶端發(fā)送 ACK 請求時,系統(tǒng)會在內(nèi)存中進(jìn)行匹配操作。這意味著,當(dāng)客戶端確認(rèn)一條消息時,系統(tǒng)會檢查這條消息是否與之前拉取的消息匹配。如果所有拉取的消息都被成功 ACK,那么 Checkpoint 對應(yīng)的位點信息就會被持久化保存。這樣,在下次拉取消息時,系統(tǒng)就會從這個持久化的位點開始,確保不會拉取到重復(fù)的消息。


          在某些情況下,比如客戶端處理消息耗時較長,再來進(jìn)行 ACK 時可能內(nèi)存中已經(jīng)沒有相關(guān)數(shù)據(jù)了。為了處理這種情況,RocketMQ 會將 Checkpoint 的消息持久化到一個特定的 Topic 中,并定期重新消費這個 Topic 的消息來進(jìn)行異步匹配。


          Pop 和 ACK 的過程主要實現(xiàn)在 PopMessageProcessor  和 PopBufferMergeService 兩個組件中。其中,MergeService 負(fù)責(zé)將 ACK 和 Checkpoint 消息進(jìn)行匹配,并在所有消息都被ACK后更新消費的進(jìn)度。


          Pop 的優(yōu)勢


          相比于 Push 模型,Pop 模型有以下優(yōu)勢:


          客戶端簡單性:由于 Pop 客戶端基于 gRPC 實現(xiàn),因此相對更簡單。這種簡單性有助于實現(xiàn)快速穩(wěn)定,并減少客戶端更新的需求。


          無狀態(tài)性:Pop 模型的無狀態(tài)特性使得切換和升級更加容易實現(xiàn)。


          多語言生態(tài)支持:利用 gRPC 的多語言支持能力,Pop 模型在生成不同語言的客戶端時能夠保持邏輯上的一致性。


          思考性問題


          為什么 Pop 客戶端會比較簡單?答:因為它基于 gRPC 客戶端實現(xiàn),而 gRPC 客戶端本身具有簡單性。


          Pop 是否可以替換 PULL,并集成到 Flink 等流平臺中?答:這是一個值得探討的問題。理論上,Pop 由于其無狀態(tài)性和簡單性,可能更適合某些流處理場景。然而,具體是否能替換 PULL 并集成到 Flink 等平臺中,還需要考慮平臺兼容性、性能需求以及業(yè)務(wù)需求等多方面因素。


          Delay Message


          RocketMQ 5.x 中的延遲消息機(jī)制與 4.x 版本有所不同。在 4.x 版本中,延遲消息是通過一個固定的 Schedule_Topic_XXXX 來實現(xiàn)的,它默認(rèn)支持最多16個隊列。每個隊列對應(yīng)一個延遲級別,并且每個級別都有一個定時器(timer)與之關(guān)聯(lián)。這些定時器會定時觸發(fā)對應(yīng)級別的延遲消息。當(dāng)某個延遲級別的消息被觸發(fā)后,系統(tǒng)會啟動一個新的定時器來處理下一個延遲級別。然而,如果支持的隊列數(shù)量過多,系統(tǒng)的負(fù)擔(dān)會加重,可能會影響整體的穩(wěn)定性。


          在 4.x 版本中,延遲消息的處理過程是這樣的:當(dāng)延遲級別的消息被觸發(fā)時,定時器中的一個報告服務(wù)(Report Service)會將該消息重新發(fā)送到正常的 Topic 中,這樣用戶就可以消費到這條消息了。但這種方式存在一些問題,比如系統(tǒng)負(fù)擔(dān)過重和穩(wěn)定性問題等。


          因此,在 RocketMQ 5.x 中,延遲消息的處理機(jī)制可能有所改進(jìn)和優(yōu)化,以解決 4.x 版本中存在的問題。


          165cf76f3a560f92f55b64b6dccb6e29.webp


          Timer Message


          在 RocketMQ 5.x 中,引入了任意維度的定時消息功能,這是一個重要的改進(jìn)。需要注意的是,延遲消息和定時消息并不完全相同。在新版本中,定時消息(也被稱作Timer Message)是通過時間輪技術(shù)來實現(xiàn)的,這種技術(shù)能夠更有效地處理和管理定時任務(wù),提高了系統(tǒng)的性能和穩(wěn)定性。


          c8289191034c1b5067a9e48bef3c89ad.webp


          RocketMQ 5.x 引入了時間輪模型來實現(xiàn)任意維度的定時消息功能,這是一個重要的技術(shù)改進(jìn)。時間輪主要由一些小格子組成,每個小格子代表一定的時間單位,在 5.x 中默認(rèn)是每秒。這些格子就像時鐘的刻度一樣,隨著時間推進(jìn)而轉(zhuǎn)動。每個格子,或者稱為 Slot,對應(yīng)一個定時消息的觸發(fā)點。


          當(dāng)時間推進(jìn)到某個特定的 Slot 時,系統(tǒng)會檢查該 Slot 中是否有定時消息需要觸發(fā)。這些消息被組織成一個鏈表,鏈表的每個節(jié)點都包含一條定時消息的相關(guān)信息。當(dāng)時間到達(dá)鏈表中某個消息的定時點時,系統(tǒng)就會觸發(fā)該消息。


          為了高效處理這些定時消息,RocketMQ 5.x 使用了指針和鏈表的數(shù)據(jù)結(jié)構(gòu)。每個 Slot 都有一個指針指向其對應(yīng)的消息鏈表,這樣系統(tǒng)就可以快速地找到并處理到期的定時消息。同時,RocketMQ 還使用了一個稱為 Timer Commit Log 的機(jī)制來順序存儲這些定時消息,以確保消息的有序性和可靠性。


          時間輪模型的好處在于它支持更大范圍的定時消息,并且性能更好。與以前的模型相比,時間輪模型可以處理更多的定時消息,同時保持較高的處理效率。此外,由于時間輪是循環(huán)的,所以它可以支持超過48小時的定時消息。當(dāng)時間超過48小時時,時間輪會回到起點并繼續(xù)下一個周期。


          在實現(xiàn)上,RocketMQ 5.x 通過異步線程池來處理消息的扭轉(zhuǎn)和觸發(fā)過程。當(dāng)一條正常的消息進(jìn)入系統(tǒng)時,它首先被發(fā)送到一個專門的 Timer Topic 中。然后,異步線程將消息轉(zhuǎn)化為時間輪格式,并生成相應(yīng)的 Timer Log 文件。接著,觸發(fā)器服務(wù)會根據(jù)時間輪的當(dāng)前位置來判斷是否有定時消息需要觸發(fā),并根據(jù) Slot 中的指針來找到并處理這些消息。


          然而,需要注意的是,雖然 RocketMQ 5.x 支持了任意維度的定時消息功能,但目前并不支持未到期消息的取消操作。這意味著一旦一條定時消息被發(fā)送出去,就無法在到期之前撤銷它。這是當(dāng)前版本的一個限制,未來可能會考慮增加相關(guān)的功能來滿足用戶的需求。


          另外,關(guān)于 4.x 版本的支持情況,目前社區(qū)上的新版本并不支持時間輪模型的任意延遲消息功能。但是,騰訊云上的 4.x 版本已經(jīng)實現(xiàn)了基于時間輪的任意延遲消息支持,為用戶提供了更多的選擇和靈活性。


          5.x  其他特性介紹


          以下是關(guān)于 RocketMQ 從4.8到5.0版本的一些重要特性的簡要解釋:


          • Dledger:這是一個容器化的存儲方案,作為第三方的 Commit Log 使用,并支持 Cloud Direct 協(xié)議的多副本功能,提供數(shù)據(jù)的冗余和可靠性。


          • Dledger Controller:這是 RocketMQ 5.x 引入的一個組件,用于控制和切換 Dledger 的組成,確保數(shù)據(jù)的一致性和高可用性。


          • Request-reply:類似于 gRPC 協(xié)議,它要求生產(chǎn)者在發(fā)送消息后必須等待消費者的確認(rèn)。只有當(dāng)消費者確認(rèn)收到消息后,生產(chǎn)者才會繼續(xù)發(fā)送下一條消息。這確保了消息的可靠傳遞,但可能會增加延遲。


          • Broker Container:這個特性允許用戶在一個進(jìn)程內(nèi)運行多個 Broker 實例,這些實例可以相互備份,提高了系統(tǒng)的容錯性和可擴(kuò)展性。


          • Logic Queue / Static Topic / Dynamic Topic:邏輯隊列是 RocketMQ 中的一個新概念,它同時支持靜態(tài) Topic 和動態(tài) Topic。靜態(tài) Topic 的隊列數(shù)量是固定的,而動態(tài) Topic 的隊列數(shù)量可以根據(jù) Broker 的數(shù)量動態(tài)調(diào)整。這對于需要靈活擴(kuò)展的系統(tǒng)非常有用。同時,邏輯隊列對應(yīng)的物理隊列可以在不影響上層應(yīng)用的情況下進(jìn)行替換或調(diào)整。


          • Light Message Queue:輕量級隊列設(shè)計用于解決大量 Topic 和源數(shù)據(jù)過大的問題。通過使用輕量級隊列,可以減小源數(shù)據(jù)的大小,提高系統(tǒng)的處理效率。


          • Compaction Topic:這個特性主要針對計算平臺,允許用戶像存儲普通 Topic 一樣存儲基于 KV 的狀態(tài)數(shù)據(jù)。它提供了寫快讀慢的特性,使得隨機(jī)讀取更加方便。這對于需要維護(hù)狀態(tài)的應(yīng)用非常有用。


          • MQTT (Millions Topic):RocketMQ 現(xiàn)在支持 MQTT 協(xié)議,這使得它能夠處理數(shù)百萬的 Topic 和隊列,并支持?jǐn)?shù)百萬甚至上億的設(shè)備連接。這對于物聯(lián)網(wǎng)等需要處理大量設(shè)備數(shù)據(jù)的場景非常有用。


          • gRPC Client:RocketMQ 5.x 引入了 gRPC 客戶端,提供了更多的通信選項和更好的跨平臺支持。


          • OT= Open Telemetry (prometheus, ot, log):這個特性主要關(guān)注可觀測性,集成了日志、Metrics 和 Tracing 等功能,可以直接與 Prometheus 等監(jiān)控系統(tǒng)集成,提供全面的系統(tǒng)監(jiān)控和診斷能力。


          ede889e3cbf7c012842ec01edb8beec2.webp

          RocketMQ 上云實踐


          容器化實踐


          容器化本質(zhì)上是為了解決交付的問題。交付在這里指的是進(jìn)程管理,進(jìn)程管理包含進(jìn)程的運行以及進(jìn)程運行時包含的資源等。進(jìn)程管理是操作系統(tǒng)的一個核心功能,它涉及到對系統(tǒng)進(jìn)程的控制,包括創(chuàng)建(Create)、讀?。≧ead,通常指查看進(jìn)程狀態(tài))、更新(Update,比如改變進(jìn)程優(yōu)先級)和刪除(Delete)進(jìn)程,類似 CRUD 操作。


          容器技術(shù),如 Docker 和 Kubernetes(K8s),提供了解決這些問題的工具和平臺。


          容器化:進(jìn)程標(biāo)準(zhǔn)化


          容器化解決了進(jìn)程標(biāo)準(zhǔn)化的問題,因為只有標(biāo)準(zhǔn)化了以后,才能批量生產(chǎn)。


          標(biāo)準(zhǔn)化有哪些?


          • 進(jìn)程和進(jìn)程的生命周期

          在 Kubernetes(K8s)中,進(jìn)程的狀態(tài)轉(zhuǎn)換被重新定義和抽象化。如果我們將傳統(tǒng)進(jìn)程的狀態(tài)轉(zhuǎn)換視為一個簡單的過程(如左圖所示),那么 Kubernetes 則為這些狀態(tài)轉(zhuǎn)換提供了一個更加復(fù)雜但更加健壯的框架(如右圖所示)。Kubernetes 追求的是“最終一致性”,這意味著當(dāng)系統(tǒng)從一個狀態(tài)向另一個狀態(tài)轉(zhuǎn)換時,它會持續(xù)進(jìn)行調(diào)度和調(diào)整,直到最終達(dá)到預(yù)期的狀態(tài)為止。這種機(jī)制確保了系統(tǒng)的穩(wěn)定性和可靠性,即使在面臨各種挑戰(zhàn)和變化時也能保持一致性。


          393bd3d6dcc6af5bccb388d3435a81b5.webp


          • 進(jìn)程管理

          當(dāng)用戶需要管理成千上萬甚至數(shù)十萬個進(jìn)程時,傳統(tǒng)的管理方式,如使用腳本或自己編寫的插件或組件,并將其嵌入到虛擬機(jī)或容器中,可能會變得非常繁瑣和復(fù)雜。然而,一旦 Kubernetes 成為管理這些進(jìn)程的標(biāo)準(zhǔn)化工具,它就會提供一套統(tǒng)一且標(biāo)準(zhǔn)化的管理方式。通過 Kubernetes 的控制器和管理器,用戶可以更加高效地管理和調(diào)度這些進(jìn)程,從而簡化管理流程并提高系統(tǒng)的可靠性和性能。


          • 進(jìn)程資源隔離

          Kubernetes 主要通過 Cgroups(控制組)來實現(xiàn) CPU 和內(nèi)存的隔離,確保每個容器都能獲得其所需的計算資源,并且不會相互干擾。同時,在網(wǎng)絡(luò)方面,Kubernetes 使用命名空間來進(jìn)行標(biāo)準(zhǔn)化的隔離,確保每個容器的網(wǎng)絡(luò)通信都是獨立且安全的。這種隔離機(jī)制使得多個容器可以在同一臺宿主機(jī)上高效、穩(wěn)定地運行,而不會相互影響。


          • 跨 AZ,跨 Region 交付

          利用 Kubernetes,用戶可以輕松實現(xiàn)跨可用區(qū)(AZ)和跨區(qū)域的交付。只需為資源打上相應(yīng)的標(biāo)簽(Tag)或(Label),或者添加一個親和性策略,即可實現(xiàn)這一目的。這些親和性策略還可以根據(jù)用戶的實際需求進(jìn)行自定義。這樣的機(jī)制大大簡化了跨地域部署和管理的復(fù)雜性。


          上圖中右邊的部分其實就是 Kubelet,K8S 對于進(jìn)程狀態(tài)的實現(xiàn),Kubelet 的實現(xiàn)。當(dāng)進(jìn)程啟動重新部署后,Kubelet 會幫用戶自動的把這三個狀態(tài)進(jìn)行扭轉(zhuǎn),直到這個狀態(tài)為最終態(tài)為止。


          容器化:運行時標(biāo)準(zhǔn)化


          • 標(biāo)準(zhǔn)化分發(fā)包

          容器化技術(shù)為軟件分發(fā)提供了標(biāo)準(zhǔn)化的方式。在進(jìn)程管理之前,應(yīng)用程序及其所有依賴項會被打包成一個容器鏡像。這種打包方式使得軟件可以方便地分發(fā)給不同的客戶,無論是私有云、公有云用戶,還是其他類型的用戶。因為容器鏡像是標(biāo)準(zhǔn)化的,所以它們可以輕松地實現(xiàn)量產(chǎn)和部署。


          • 標(biāo)準(zhǔn)化運行環(huán)境

          除了分發(fā)包外,容器化技術(shù)還標(biāo)準(zhǔn)化了進(jìn)程的運行環(huán)境。這意味著無論進(jìn)程是否依賴于特定的系統(tǒng)庫(如 SMD、library、SO 等)或 Java 的 JDK 等組件,容器都能提供一個一致的運行環(huán)境。


          在下圖中,這種標(biāo)準(zhǔn)化運行環(huán)境主要分為兩層:


          靜態(tài)層 - 鏡像(Image):這一層包含了應(yīng)用程序運行所需的所有靜態(tài)依賴項。例如,Java 應(yīng)用程序可能包含 JDK、阿爾薩斯調(diào)試工具等;C++ 或 Python 程序可能依賴于特定的庫或第三方共享對象(SO)。這些依賴項都被標(biāo)準(zhǔn)化并封裝在容器鏡像中。鏡像采用分層存儲的方式,每一層都存儲了不同的內(nèi)容,最終為應(yīng)用程序提供了一個完整的運行環(huán)境。


          動態(tài)層 - 容器(Container):當(dāng)從鏡像啟動一個實例時,就創(chuàng)建了一個容器。這個容器是動態(tài)的,它包含了進(jìn)程運行時所需的資源(如 CPU、內(nèi)存)、持久化卷聲明(PVC)、配置信息以及網(wǎng)絡(luò)設(shè)置等。這些資源在進(jìn)程啟動并轉(zhuǎn)化為容器時由容器運行時自動初始化。這種標(biāo)準(zhǔn)化的環(huán)境確保了無論在 Kubernetes 環(huán)境的哪個部分運行容器,其表現(xiàn)都是一致的。


          通過這種方式,容器化技術(shù)大大簡化了軟件分發(fā)和部署的復(fù)雜性,同時確保了應(yīng)用程序在不同環(huán)境中都能以一致和可靠的方式運行。


          容器化其他優(yōu)勢


          只有有了標(biāo)準(zhǔn)化的進(jìn)程,標(biāo)準(zhǔn)化的運行環(huán)境和定義的進(jìn)程生命周期之后,才能做到標(biāo)準(zhǔn)化和分發(fā)。這時候用戶的擴(kuò)容縮容運維才會更方便。


          • 快速擴(kuò)容 / 縮容

          • 標(biāo)準(zhǔn)化運維

          • 多進(jìn)程 HA,跨 AZ、跨 Region 交付更簡單

          • 交付更快、更可靠


          容器化:提高資源利用率


          容器化通過標(biāo)準(zhǔn)化進(jìn)程管理,使得用戶可以輕松地同時管理多達(dá)50萬個進(jìn)程,這不僅簡化了進(jìn)程管理的復(fù)雜性,還提高了資源的利用率。然而,對于許多企業(yè)決策者來說,他們更關(guān)心的是容器化是否能夠真正實現(xiàn)降本增效。


          事實上,降本增效是一個包含兩個方面的目標(biāo),而這兩個目標(biāo)往往難以同時實現(xiàn)。容器化主要貢獻(xiàn)在于提高資源利用率。在傳統(tǒng)的管理方式下,進(jìn)程往往是散亂分布的,很難確保資源得到最大化利用。進(jìn)程與進(jìn)程之間可能存在較大的資源間隙。但是,通過 Kubernetes 的標(biāo)準(zhǔn)化管理,每個進(jìn)程都可以根據(jù)實際需求進(jìn)行資源申請。Kubernetes 使用 Cgroups 等技術(shù)對 CPU 和內(nèi)存進(jìn)行隔離,確保所有資源都在一個統(tǒng)一的資源池中進(jìn)行分配。


          這種資源池的方式意味著系統(tǒng)可以根據(jù)實際需求動態(tài)地分配資源,盡可能保持 CPU 利用率在40%或50%以上,從而提高整體資源利用率。這就像是在一個大家庭中共享食物和水源,每個人都可以按需取用,避免了浪費。


          然而,盡管容器化可以提高資源利用率,但它并不能直接降低成本。正如一位 Kubernetes 領(lǐng)域的大佬所說:“RocketMQ 就是一個人,容器化前吃喝多少,容器化后也會吃喝多少!”這意味著無論是否進(jìn)行容器化,系統(tǒng)的總體資源消耗并不會減少。因此,我們不能期望通過容器化來直接降低成本。但是,通過提高資源利用率,企業(yè)可以更加高效地利用現(xiàn)有資源,從而間接地實現(xiàn)成本優(yōu)化和效率提升。


          608b3163a9c399761a62e787c4af8458.webp


          RocketMQ 容器化需要重點關(guān)注哪些呢?


          容器化:選擇容器平臺


          騰訊內(nèi)部有多套容器化平臺:TKE 標(biāo)準(zhǔn)版, TKE Serverless 等,都是久經(jīng)考驗的,穩(wěn)定可靠。騰訊云 RocketMQ 是基于 TKE Serverless 容器平臺打造。


          TKE Serverless 是騰訊云推出的無須用戶購買節(jié)點即可部署工作負(fù)載的服務(wù)模式,集群完全兼容原生 Kubernetes,支持使用原生方式購買及管理資源,按照容器真實使用的資源量計費。TKE Serverless 集群還擴(kuò)展支持騰訊云的存儲及網(wǎng)絡(luò)等產(chǎn)品,同時確保用戶容器的安全隔離,開箱即用。


          在 RocketMQ 容器化選擇容器平臺時,主要考慮


          • 是否需要備貨

                 TKE Serverless 無需備貨。貨源在大池子里,無需購買 Node 添加到容器平臺,大池子貨源相對充足。當(dāng)然也能提高大池子資源利用率。

          • 按使用量付費,不浪費 CPU、Mem

          • 支持固定 IP

                  在 Pod 重啟前后,Pod IP 保持不變。

          • 支持 VPC-CNI(IP 打平)


          容器化:復(fù)雜的網(wǎng)絡(luò)


          a909f1787300e53424859cdc706c5c25.webp


          容器化網(wǎng)絡(luò)之所以復(fù)雜,原因在于同一個 RocketMQ 集群需要為多種場景提供服務(wù)。這些場景可能包括位于騰訊不同 VPC(虛擬私有云)內(nèi)的服務(wù)、公網(wǎng)上的服務(wù)、開發(fā)調(diào)試環(huán)境、辦公環(huán)境,甚至是位于客戶自建機(jī)房或其他云服務(wù)提供商的服務(wù)。每種場景的網(wǎng)絡(luò)環(huán)境都各不相同,且彼此間可能并不直接相通。


          當(dāng)用戶嘗試訪問 RocketMQ 集群時,他們通常首先從服務(wù)器獲取路由信息,這些信息會返回一個 IP 列表,然后用戶通過這個列表與 RocketMQ 集群進(jìn)行交互。但是,難點在于如何讓這同一套 RocketMQ 集群能夠適應(yīng)并處理上述所有不同場景的網(wǎng)絡(luò)接入需求。


          為了解決這個問題,我們需要實現(xiàn)網(wǎng)絡(luò)的打通,并確保路由信息的實時更新。當(dāng)網(wǎng)絡(luò)策略發(fā)生變化時,這些路由信息必須能夠迅速、準(zhǔn)確地反映最新的網(wǎng)絡(luò)狀態(tài)。這樣,無論用戶從哪個環(huán)境、哪個位置訪問,都能順暢地連接到 RocketMQ 集群,獲取所需的服務(wù)。這是一個既具挑戰(zhàn)性又十分必要的任務(wù),以確保 RocketMQ 集群的高效、穩(wěn)定運行。


          容器化其他問題


          1、配置一致性問題

          容器化 RocketMQ 時,配置文件可以通過 Config Map 下發(fā)。同時在不重啟進(jìn)程的前提下,也可以通過 Admin API 修改,兩者需要保持?jǐn)?shù)據(jù)一致。


          2、存儲問題

          在重啟前后,配置文件、數(shù)據(jù)文件所掛載的 PVC 需要保持不變。


          3、公有云、私有化兼顧問題

          做資源層抽象,可以同時適配公有云和私有化的各種容器平臺,甚至非容器平臺。


          4、Yaml 、 Helm Chart 、 Operator, 怎么選?


          1ff35c1cebf69f1eeb5b8a1570591052.webp


          分層存儲實踐


          分層存儲架構(gòu)


          c2ecef1b84ad1a969a9d560c17f50f60.webp


          上圖主要描述了兩個分發(fā)過程:Commit log 的分發(fā)和分層存儲的分發(fā)。


          對于 Commit log 的分發(fā),它與常規(guī)流程相同。當(dāng)用戶發(fā)送一條消息時,該消息會被寫入 Commit log 中。隨后,通過兩個異步的 Dispatcher,系統(tǒng)會分發(fā)并構(gòu)建 Consumer Queue 的索引和 Index 索引。


          在 5.x 版本中,分層存儲的實現(xiàn)是通過新增一個 Dispatcher 來實現(xiàn)的。這個新的 Dispatcher 會被注冊到原有的 Dispatcher 中。當(dāng)用戶寫入數(shù)據(jù)時,數(shù)據(jù)會異步地分發(fā)到分層存儲的 Commit log 里。一旦數(shù)據(jù)被分發(fā)到這里,新的 Dispatcher 會負(fù)責(zé)將數(shù)據(jù)最終分發(fā)到 Index File 或 Consumer Queue 中。這些 Index File 和 Consumer Queue 的底層實際上是通過騰訊云上的對象存儲來實現(xiàn)的。因此,文件會被存儲在騰訊云的對象存儲里。這個異步分發(fā)過程與 Commit log 的分發(fā)過程非常相似。


          在生產(chǎn)過程中,數(shù)據(jù)會經(jīng)歷上述的分發(fā)和存儲過程。而在消費過程中,系統(tǒng)會首先嘗試從緩存中讀取數(shù)據(jù)。如果緩存中的消息數(shù)量不足,系統(tǒng)會通過 Consumer Queue 和 Commit log 的 Offset 來定位并讀取分層存儲中的數(shù)據(jù)。主要的過程仍然涉及到 Dispatcher 和數(shù)據(jù)的讀取。


          簡而言之,這段描述解釋了在一個消息系統(tǒng)中,消息是如何被寫入、分發(fā)、存儲和讀取的,特別是涉及到 Commit log 和分層存儲的部分。


          分層存儲優(yōu)勢


          • Topic TTL(自研支持,社區(qū)不支持)

          • 冷熱數(shù)據(jù)分級存儲

          • 真正海量、低成本存儲


          分布式限流實踐


          分布式限流架構(gòu)


          cc89d6eb67c5bf31aebc483ac82741a0.webp


          在 5.x 版本中,我們引入了分布式限流機(jī)制,這實際上是對集中限流的一種補(bǔ)充。在共享集群中,由于存在多租戶隔離的需求,我們希望每個用戶都能按照其購買的 TPS (每秒傳輸次數(shù))進(jìn)行使用,而不影響其他用戶。因此,當(dāng)用戶超過其購買的 TPS 時,我們會對其進(jìn)行限流,以確保整個系統(tǒng)的穩(wěn)定性和公平性。


          當(dāng)然,在實施限流的同時,我們也會向用戶發(fā)送告警信息,讓他們知道當(dāng)前的流量已經(jīng)超過了限制,需要采取相應(yīng)措施進(jìn)行控制。


          那么,為什么在 5.x 版本中需要引入分布式限流呢?這主要是因為 RocketMQ Proxy 在處理流量時存在一些熱點問題。盡管 Proxy 現(xiàn)在是無狀態(tài)的,但在處理客戶端連接、消息生產(chǎn)和消費確認(rèn)(ACK)時,仍然存在一定的局限性。具體來說,當(dāng)一個客戶端連接到某個 Proxy 進(jìn)行消息生產(chǎn)或消費時,該 Proxy 會負(fù)責(zé)處理所有的 ACK 確認(rèn)信息。這是因為只有該 Proxy 才能識別并處理相應(yīng)的 Check Point 信息。因此,當(dāng)某個 Proxy 上的消息流量過大時,其他 Proxy 無法有效地分擔(dān)其壓力。


          為了解決這個問題,我們引入了分布式限流機(jī)制。在這個機(jī)制中,我們設(shè)置了一個集中的管理節(jié)點,負(fù)責(zé)定期向各個 Proxy 節(jié)點下發(fā)流量配額(Quota)。這樣一來,即使某個 Proxy 節(jié)點上的流量過大,也能通過限流機(jī)制確保整個系統(tǒng)的穩(wěn)定性和可用性。同時,這也使得其他 Proxy 節(jié)點能夠在必要時提供一定的支持,從而更有效地利用系統(tǒng)資源。


          分布式限流特點


          • 限流類型:全局 or 本地。

          • 限流維度:標(biāo)簽鍵值對,客戶端通過標(biāo)簽匹配規(guī)則。

          • 限流閾值:請求數(shù)/統(tǒng)計周期,如 1000/s。

          • 降級策略:當(dāng)網(wǎng)絡(luò)等原因?qū)е抡埱?Server 失敗時,降級為單機(jī)限流 or 直接放行。

          • 限流效果:快速失敗 or 均勻排隊。

          • 優(yōu)先級:0-9降序,適用多條規(guī)則匹配的場景,例如通配符和精確匹配。


          ede889e3cbf7c012842ec01edb8beec2.webp

          未來規(guī)劃


          未來,作者將繼續(xù)致力于 RocketMQ 的社區(qū)布道工作,通過撰寫技術(shù)文章、參與技術(shù)交流活動等方式,讓更多開發(fā)者了解并熟悉 RocketMQ 4.x 及 5.x 版本的新特性,推動其在行業(yè)內(nèi)的廣泛應(yīng)用。同時,作為公司與社區(qū)之間的橋梁,他將積極分享騰訊云上關(guān)于 RocketMQ 的實踐經(jīng)驗和代碼,將久經(jīng)考驗的技術(shù)成果回饋給社區(qū),助力開源生態(tài)的繁榮發(fā)展。


          在職業(yè)發(fā)展上,作者堅信穩(wěn)定性是任何系統(tǒng)的基石,因此他將持續(xù)關(guān)注并提升 RocketMQ 在穩(wěn)定性和可靠性方面的表現(xiàn)。此外,作者將始終堅持以用戶價值為導(dǎo)向,深入了解用戶的需求和痛點,通過技術(shù)創(chuàng)新和產(chǎn)品優(yōu)化,為用戶提供更加高效、便捷的消息流處理解決方案。值得一提的是,騰訊云 RocketMQ 5.x Serverless 版本已經(jīng)上線,這一新版本將為用戶帶來更多便利和可能性,歡迎大家積極體驗并提出寶貴意見。


          展望未來,期待與更多同行攜手合作,共同推動 RocketMQ 在云原生消息流系統(tǒng)領(lǐng)域的發(fā)展,為企業(yè)的數(shù)字化轉(zhuǎn)型提供強(qiáng)有力的技術(shù)支持。


          ede889e3cbf7c012842ec01edb8beec2.webp

          總結(jié)


          Apache RocketMQ 是一個可靠、高吞吐量、分布式的消息隊列服務(wù)。 騰訊云作為中國領(lǐng)先的云計算服務(wù)商之一,也大規(guī)模的提供了 Apache RocketMQ 服務(wù)。同時,騰訊云也對 Apache RocketMQ 進(jìn)行了一系列優(yōu)化和定制,以更好地適應(yīng)公有云復(fù)雜的業(yè)務(wù)需求。 在這個過程中,騰訊云也積累了大量的經(jīng)驗和技術(shù),包括如何優(yōu)化 Apache RocketMQ 的性能、如何提高其可靠性、如何進(jìn)行監(jiān)控和調(diào)優(yōu)等方面。這些經(jīng)驗對于其他企業(yè)和開發(fā)者也具有很大的參考價值, 希望通過以上文章的深入剖析,能夠為廣大技術(shù)同行提供有益的參考和啟示。


          往期

          推薦


          《云原生 API 網(wǎng)關(guān)鏈路追蹤能力重磅上線

          Kafka 分級存儲在騰訊云的實踐與演進(jìn)

          Apache RocketMQ 5.0 騰訊云落地實踐

          RocketMQ 5.X PopAck 源碼拆解

          CKafka 一站式搭建數(shù)據(jù)流轉(zhuǎn)鏈路,助力長城車聯(lián)網(wǎng)平臺降低運維成本》



          8beab2477a47704fd7924b7e2519951a.webp


          掃描下方二維碼關(guān)注本公眾號,

          了解更多微服務(wù)、消息隊列的相關(guān)信息!

          解鎖超多鵝廠周邊!

          戳原文,查看更多消息隊列 RocketMQ 版的信息!

          點個在看你最好看


          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲AV高清在线观看 | 看日韩的黄色片 | 国产乱视频 | 日韩日韩日韩日韩AV | 日骚逼视频 |