導語:RocketMQ 用戶能夠無縫遷移到 Apache Pulsar 了。自此,Apache Pulsar 補齊了兼容主流消息隊列協議的能力。java
咱們很高興地宣佈騰訊雲中間件開源 RoP!RoP 將 RocketMQ 協議處理插件引入 Pulsar broker,這樣 Pulsar 就能支持原生 RocketMQ 協議了。git
做者 | 冉小龍 騰訊高級工程師,Apache Pulsar Committer,Apache BookKeeper Contributorgithub
什麼是RoP
什麼是高可用性
與 KoP、MoP 和 AoP 類似,RoP 是一種可插拔的協議處理插件。apache
將 RoP 協議處理插件添加到現有 Pulsar 集羣后,用戶無需修改代碼,便能將現有的 RocketMQ 應用程序和服務遷移到 Pulsar,同時還能使用 Pulsar 的強大功能,例如:微信
•計算與存儲分離架構
•多租戶app
•跨地域複製框架
•分層分片分佈式
•輕量化計算框架 -- Pulsar Functions函數
•...
爲何開發RoP
Apache Pulsar 是下一代雲原生分佈式消息流平臺,集消息、存儲、輕量化函數式計算爲一體。自 2016 年開源以來,Pulsar 已被普遍採用,並於 2018 年被指定爲 Apache 頂級項目。
RocketMQ 是一款強大的開源分佈式消息系統,基於高可用分佈式集羣技術,提供低延時的、高可靠的消息發佈與訂閱服務。
Pulsar 和 RocketMQ 擁有普遍的用戶羣體和強勁的開發支持,全球許多頭部公司都在使用這兩種消息服務。同時,咱們也收到了用戶的需求,但願能在 Pulsar 與 RocketMQ 之間傳輸數據,並充分利用這兩種消息系統的優點。
Apache Pulsar 經過對 Consumer 層的抽象,提供了隊列和流兩種消費模型的統一抽象。在 Client 與 Broker 的交互中,Pulsar 基於 Protobuf 的二進制協議,提供更高的性能和更低的延遲。除此以外,經過 Protobuf 協議,Pulsar 能夠更容易地支持並實現多語言的客戶端,好比:Java、CPP、Python 和 Go 語言等客戶端。
可是,對於使用其餘消息傳輸協議編寫的應用程序(例如,RocketMQ),因爲使用的消息處理協議和 Pulsar 不一樣,若是 Pulsar 想要兼容 RocketMQ 協議,爲了將 RocketMQ 的協議適配到 Pulsar 的消息協議層中,用戶須要重寫整個協議層,這給用戶的遷移和切換帶來了很大的成本。
爲了解決這個問題,最直觀的處理方式是使用相似 Pulsar Connector 的形式,將用戶在 RocketMQ 中的現存數據經過 RocketMQ Wrapper 的方式導入到 Pulsar 集羣,可是這須要業務端更改本身的業務代碼邏輯,同時須要確保兩邊的數據可以保證一致,這給使用 RocketMQ 的用戶帶來了很大的技術挑戰。因此,可否給用戶提供一個開箱即用的遷移策略和方案而且用戶無需作任何代碼修改呢?這即是 RoP 誕生的最初目的。
Apache Pulsar 在 PIP-41中介紹了一種全新的接入方式。經過在 Broker 端暴露 Protocol Handler 插件,將 Netty 的 channel 和 Pulsar 的 Broker Service) 對象暴露給用戶。這容許用戶直接操做和調用 Pulsar 中比較低階的 API(例如:PersistentTopic 和 ManagerLedger)。基於這個協議,用戶無需更改代碼,只需將服務請求轉發到 RoP 中,RoP 利用 Protocol Handler 的插件將用戶的請求轉發到 Pulsar 中便可。
怎麼開發RoP
RoP架構
經過對比 Pulsar 和 RocketMQ 之間的協議能夠發現,兩者在消息處理的思路上有很多類似之處,好比這兩種協議都包含以下操做:
Topic Lookup: 全部 Clients 與任意 Broker 創建鏈接以前,會先去查找當前 Topic 的 Owner Broker。獲取到對應的 metadata 以後,Clients 會與 Owner Broker 之間創建 TCP 鏈接進行數據的交互。
- Produce: Clients 與 Topic 所在的全部 Owner Broker 之間進行通訊並將消息 append 到對應的分佈式日誌中。
- Consume: Clients 與 Topic 所在的全部 Owner Broker 之間進行通訊並從分佈式日誌中讀取指定的消息。
- Offset: Producer 生產到 topic 中的消息會分配一個惟一的 offset,Pulsar 中使用 MessageID 來標識 offset。消費者能夠經過 offset 去日誌中獲取指定位置的消息。
Apache Pulsar 的存儲層使用了 Apache BookKeeper,Pulsar 至關於 BookKeeper 的 Client,經過調用 ManagerLedger 對象可以很容易的達到爲分佈式日誌操做的目的。基於此,RoP 能夠很好的將 RocketMQ 中對 commitLog 和 queueLog 的操做映射到 BookKeeper 中來。
RoP概念
Offset 和 MessageID
在 RocketMQ 中,使用 offset 來標識消息的位置,當消息被生產到指定的 Topic 以後,會爲每個消息分配一個惟一的 offset;在 Pulsar 中,使用 MessageID 來惟一標識每條消息,每個 MessageID 由三部分組成,ledgerID、entryID 和 partitionID。咱們經過合理的劃分將 messageID 和 offset 進行映射,來惟一標識 Topic 中的每一條消息。
Message
對於一條消息,RocketMQ 和 Pulsar 都包含消息的 headers 和 payload 等字段,經過對消息協議的解析,咱們能夠輕鬆的將 RocketMQ message 轉換爲 Pulsar 的 message 格式。爲了更好的兼容 Tag 消息的功能,在消息協議的處理方面增長了 8 字節的特殊字段,用來區分該消息是否屬於 Tag 消息。
Topic Lookup
在 Pulsar 中,client 與 broker 創建鏈接以前,會根據當前傳入的 Topic 執行 Lookup 操做,在 Broker 集羣中尋找當前 Topic 所在的 Owner Broker,而後將該 Owner Broker 的地址返回並與 client 創建 TCP 鏈接,再進行數據交互。在 RocketMQ 中,client 與 broker 創建鏈接以前,會先處理 GET_ROUTEINTO_BY_TOPIC 命令,獲取 topic 所在的路由信息後,創建對應的 TCP 鏈接,再進行數據交互。
如何使用RoP
目前,RoP 發佈了 0.1.0 版本,你能夠用過如下任一方式參與該項目:
想上手試試?
可在如下網址下載 RoP 和查閱用戶指南。不管是快速啓動 standalone RoP 或在現有 Pulsar 集羣中部署 RoP,均可輕鬆實現。
另外,爲了方便快速使用並驗證 RoP,咱們提供了 RocketMQ 的常見使用場景和用例,你能夠直接使用這些代碼示例驗證服務:https://github.com/streamnative/rop/tree/master/examples/src/main/java/org/streamnative/rocketmq/example。
想解決問題?
若有任何問題,能夠在 RoP GitHub repo 中 建立 issue 或加入 RoP 微信羣進行討論。不管哪一種方式,RoP 資深專家都隨時在線:https://github.com/streamnative/rop/issues/new。
想參與貢獻?
RoP 源碼開放並託管在 GitHub 上:https://github.com/streamnative/rop。 如需改進功能或修復 bug,歡迎提交 PR。
特別鳴謝
在此特別鳴謝騰訊雲中間件團隊張勇華、冉小龍、韓明澤、夏子承等同窗的支持,以及StreamNative 在架構設計以及方案的良好建議,共同推動了 RoP 項目的順利落地。從此雙方將繼續攜手並進、砥礪前行,爲消息服務貢獻更多力量!