下一代分散式訊息佇列Apache Pulsar從入門到實現
Pulsar簡介
Apache Pulsar是一個企業級的分散式訊息系統,最初由Yahoo開發並在2016年開源,目前正在Apache基金會下孵化。Plusar已經在Yahoo的生產環境使用了三年多,主要服務於Mail、Finance、Sports、 Flickr、 the Gemini Ads platform、 Sherpa以及Yahoo的KV儲存。
Pulsar之所以能夠稱為下一代訊息佇列,主要是因為以下特性:
-
線性擴充套件。能夠絲滑的擴容到成百上千個節點(Kafka擴容需要佔用很多系統資源在節點間拷貝資料,而Plusar完全不用)
-
高吞吐。已經在Yahoo的生產環境中經受了考驗,每秒數百萬訊息
-
低延遲。在大規模的訊息量下依然能夠保持低延遲(< 5ms)
-
持久化機制。Plusar的持久化機制構建在Apache BookKeeper之上,提供了寫與讀之前的IO隔離
-
基於地理位置的複製。Plusar將多地域/可用區的複製作為首要特性支援。使用者只需配置好可用區,訊息就會被源源不斷的複製到其他可用區。當某一個可用區掛掉或者發生網路分割槽,plusar會在之後不斷的重試。
-
部署方式的多樣化。既可以執行在裸機,也支援目前例如Docker、K8S的一些容器化方案以及不同的雲廠商,同時在本地開發時也只需要一行命令即可啟動整個環境。
-
Topic支援多種消費模式:exclusive、shared、failover
架構概述
從最上層來看,一個Plusar單元由若干個叢集組成,單元內的叢集可以互相之前複製資料, plusar中通常有以下幾種元件:
-
Broker:負責處理Producer發來的訊息並分發給消費者。通過一個全域性的ZK叢集來處理多種協作式任務,例如說基於地理位置的複製。並將訊息儲存到BookKeeper中,同時單個叢集內也需要有一套ZK叢集,來儲存一些後設資料。
-
BookKeeper叢集: 內部包含多個bookies,用於持久化訊息。
-
ZooKeeper集
Broker
在Kafka和RocketMQ中,Broker負責訊息資料的儲存以及consumer消費位移的儲存等,而Plusar中的broker和他們兩個有所不同,plusar中的broker是一個無狀態的節點,主要負責三件事情:
-
暴露REST介面用於執行管理員的命令以及topic所有者的查詢等
-
一個用於節點間通訊的非同步的TCP伺服器,協議目前採用的是Google之前開源的Protocol Buffer
-
為了支援地域複製,broker會將自己 叢集所在的訊息釋出到其他可用區。
訊息會被先發布到BookKeeper中,然後會在Broker本地記憶體中快取一份,因此一般來說訊息的讀取都會從從記憶體中讀取,因此第一條中所說的查詢topic所有者就是說,因為BookKeeper中的一個ledger只允許一個writer,因此我們可以呼叫rest介面獲取到某一個topic當前的所有者。
BookKeeper
BookKeeper是一個可橫向擴充套件的、錯誤容忍的、低延遲的分散式儲存服務,BookKeeper中最基本的單位是記錄,實際上就一個位元組陣列,而記錄的陣列稱之為ledger,BK會將記錄複製到多個bookies,儲存ledger的節點叫做bookies,從而獲得更高的可用性和錯誤容忍性。從設計階段BK就考慮到了各種故障,Bookies可以當機、丟資料、髒資料,但是主要整個叢集中有足夠的Bookies服務的行為就是正確的。
在Pulsar中,每個分割槽topic是由若干個ledger組成的,而ledger是一個append-only的資料結構,只允許單個writer,ledger中的每條記錄會被複制到多個bookies中,一個ledger被關閉後(例如broker當機了或者達到了一定的大小)就只支援讀取,而當ledger中的資料不再需要的時候(例如所有的消費者都已經消費了這個ledger中的訊息)就會被刪除。
Bookkeeper的主要優勢在於它可以保證在出現故障時在ledger的讀取一致性。因為ledger只能被同時被一個writer寫入,因為沒有競爭,BK可以更高效的實現寫入。在Broker當機後重啟時,Plusar會啟動一個恢復的操作,從ZK中讀取最後一個寫入的Ledger並讀取最後一個已提交的記錄,然後所有的消費者也都被保證能看到同樣的內容。
我們知道Kafka在0.8版本之前是將消費進度儲存到ZK中的,但是ZK本質上基於單個日誌的中心服務,簡單來講,ZK的效能不會隨著你增加更多的節點而線性增加,會只會相反減少,因為更多的節點意味著需要將日誌同步到更多的節點,效能也會隨之下降,因此QPS也會受單機效能影響,因此0.8版本之後就將消費進度儲存到了Kafka的Topic中,而RocketMQ最初的版本也類似,有幾種不同的實現例如ZK、資料庫等,目前版本採用的是儲存到本機檔案系統中,而Plusar採用了和Kafka類似的思想,Plusar將消費進度也儲存到了BK的ledger中。
後設資料
Plusar中的後設資料主要儲存到ZK中,例如不同可用區相關的配置會存在全域性的ZK中,叢集內部的ZK用於儲存例如某個topic的資料寫入到了那些Ledger、Broker目前的一些埋點資料等等。
Plusar核心概念
Topic
釋出訂閱系統中最核心的概念是topic,簡單來說,topic可以理解為一個管道,producer可以往這個管道丟訊息,consumer可以從這個管道的另一端讀取訊息,但是這裡可以有多個consumer同時從這個管道讀取訊息。
每個topic可以劃分為多個分割槽,同一個topic下的不同分割槽所包含的訊息都是不同的。每個訊息在被新增到一個分割槽後都會分配一個唯一的offset,在同一個分割槽內訊息是有序的,因此客戶端可以根據比如說使用者ID進行一個雜湊取模從而使得整個使用者的訊息都發往整個分割槽,從而一定程度上避免race condition的問題。
通過分割槽,將大量的訊息分散到不同的節點處理從而獲得高吞吐。預設情況下,plusar的topic都是非分割槽的,但是支援通過cli或者介面建立一定分割槽數目的topic。
預設情況下Plusar會自動均衡Producer和Consumer,但有時候客戶端想要根據自己的業務規則也進行路由,Plusar預設支援以下幾種規則:單分割槽、輪詢、雜湊、自定義(即自己實現相關介面來定製路由規則)
消費模式
消費決定了訊息具體是如何被分發到消費者的,Plusar支援幾種不同的消費模式: exclusive、shared、failover。圖示如下:
-
Exclusive: 一個topic只能被一個消費者消費。Plusar預設就是這個模式
-
Shared: 共享模式或者叫輪詢模式,多個消費者可以連線到同一個topic,訊息被依次分發給消費者,當一個消費者當機或者主動斷開連線,那麼發到那個消費者的還沒有ack的訊息會得到重新排程分發給其他消費者。
-
Failover: 多個消費者可以連線同一個topic並按照字典序排序,第一個消費者會開始消費訊息,稱之為master,當master斷開連線,所有未ack和佇列中剩下的訊息會分發給另一個消費者。
Plusar目前也支援另一種Reader介面,支援傳入一個訊息ID,例如說Message.Earliest來從最早的訊息開始消費。
總結
Plusar作為下一代分散式訊息佇列,擁有非常多吸引人的特性,也彌補了一些其他競品的短板,例如地域複製、多租戶、擴充套件性、讀寫隔離等等。
【原文連結:https://github.com/aCoder2013/blog/issues/23,作者:SongWang】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31077337/viewspace-2168643/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Pulsar 入門實戰(1)--Pulsar 訊息傳遞
- 訊息佇列之-RocketMQ入門佇列MQ
- 分散式訊息佇列知識圖譜分散式佇列
- Redis實現訊息佇列Redis佇列
- 譯文|如何將 Pulsar 用作訊息佇列佇列
- 分散式訊息佇列RocketMQ--事務訊息--解決分散式事務的最佳實踐分散式佇列MQ
- 分散式之訊息佇列複習精講分散式佇列
- 分散式訊息佇列:如何保證訊息的順序性分散式佇列
- 什麼是Rabbitmq訊息佇列? (安裝Rabbitmq,透過Rabbitmq實現RPC全面瞭解,從入門到精通)MQ佇列RPC
- Spring Boot中使用WebSocket總結(三):使用訊息佇列實現分散式WebSocketSpring BootWeb佇列分散式
- 分散式訊息佇列:如何保證訊息不被重複消費?(訊息佇列消費的冪等性)分散式佇列
- 分散式任務 + 訊息佇列框架 go-queue分散式佇列框架Go
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- 分散式服務(RPC)+分散式訊息佇列(MQ)面試題精選分散式RPC佇列MQ面試題
- 為什麼分散式一定要有訊息佇列?分散式佇列
- 從 Kafka 到 Pulsar,BIGO 打造實時訊息系統之路KafkaGo
- RabbitMQ .NET訊息佇列使用入門(五)【RabbitMQ例子】MQ佇列
- 如何實現MQ佇列訊息監控MQ佇列
- Redis 竟然能用 List 實現訊息佇列Redis佇列
- 訊息佇列在大型分散式系統中的實戰要點分析!佇列分散式
- 基於訊息佇列 RocketMQ 的大型分散式應用上雲最佳實踐佇列MQ分散式
- 老生常談——利用訊息佇列處理分散式事務佇列分散式
- Apache Pulsar分散式事務機制Apache分散式
- 訊息佇列系列一:訊息佇列應用佇列
- 實現簡單延遲佇列和分散式延遲佇列佇列分散式
- RabbitMQ .NET訊息佇列使用入門(四)【RabbitMQ用法大全】MQ佇列
- 訊息佇列佇列
- Go中使用Redis實現訊息佇列教程GoRedis佇列
- 訊息佇列 RocketMQ 5.0:從訊息服務到雲原生事件流平臺佇列MQ事件
- 分散式訓練從入門到放棄分散式
- PHP基於Redis訊息佇列實現的訊息推送的方法PHPRedis佇列
- Redis 使用 List 實現訊息佇列能保證訊息可靠麼?Redis佇列
- 入門RabbitMQ訊息佇列,看這篇文章就夠了MQ佇列
- 萬字長文:從 C# 入門學會 RabbitMQ 訊息佇列程式設計C#MQ佇列程式設計
- 用訊息佇列和socket實現聊天系統佇列
- RabbitMQ 訊息佇列之佇列模型MQ佇列模型
- kafka 訊息佇列Kafka佇列
- 訊息佇列(MQ)佇列MQ