「分佈式系統前沿技術」專題 | Pulsar 的設計哲學

分佈式技術的發展,深入地改變了咱們編程的模式和思考軟件的模式。值 2019 歲末,PingCAP 聯合 InfoQ 共同策劃出品「分佈式系統前沿技術 」專題, 邀請衆多技術團隊共同參與,一塊兒探索這個古老領域的新生機。本文出自 StreamNative 聯合創始人 Sijie Guo。

幾十年前,消息隊列開始興起,它用於鏈接大型機和服務器應用程序,並逐漸在企業的服務總線與事件總線設計模式、應用間的路由和數據遷移中發揮相當重要的做用。自此,應用程序架構和數據角色經歷了重大變化:例如,面向服務的架構、流處理、微服務、容器化、雲服務和邊緣計算,這些只是諸多變化中的冰山一角。這些變化創造了大量的新需求,這些新需求遠遠超出了原有消息隊列的技術能力。數據庫

爲了知足這些需求,處理消息隊列的全新方法應運而生。現代應用對消息解決方案的要求不只僅是主動鏈接、移動數據,而是要在持續增加的服務和應用中智能處理、分析和傳輸數據,而且在規模持續擴大的狀況下不增長運營負擔。編程

爲了知足上述要求,新一代的消息傳遞和數據處理解決方案 Apache Pulsar 應運而生。Apache Pulsar 起初做爲消息整合平臺在 Yahoo 內部開發、部署,爲 Yahoo Finance、Yahoo Mail 和 Flickr 等雅虎內部關鍵應用鏈接數據。2016 年 Yahoo 把 Pulsar 開源並捐給 Apache 軟件基金會(ASF),2018 年 9 月 Pulsar 畢業成爲 ASF 的頂級項目,逐漸從單一的消息系統演化成集消息、存儲和函數式輕量化計算的流數據平臺。設計模式

Pulsar 的設計是爲了方便和現有的 Kafka 部署集成,同時也方便開發人員將其鏈接到應用程序。Pulsar 最初就是爲鏈接 Kafka 構建的。Pulsar 提供和 Kafka 兼容的 API,無需更改代碼,只要使用 Pulsar 客戶端庫從新編譯,現有應用程序便可鏈接到 Kafka。Pulsar 還提供內置的 Kafka 鏈接器,能夠消費 Kafka topic 的數據或將數據發佈到 Kafka topic。緩存

系統架構是軟件最底層的設計決策,一旦實施,就很難改變。架構決定了軟件特性和根本不一樣。Apache Pulsar 在功能上有不少優點,例如統一的消費模型,多租戶,高可用性等等,但最本質、最重要的區別仍是 Apache Pulsar 的系統架構。Apache Pulsar 的設計架構與其餘消息傳遞解決方案(包括 Apache Kafka)的架構有着本質不一樣,Pulsar 從設計時就採用了分層分片式的架構,以提供更好的性能、可擴展性和靈活性。服務器

現實生活中,存在的消息系統有不少,Yahoo 爲何研發本身的消息系統呢?由於已有的消息系統沒法解決 Yahoo 遇到的問題和規模,Yahoo 須要多租戶,可以支撐上百萬的 topics,同時知足低延遲、持久化和跨地域複製要求。而現有的消息系統,存在以下諸多問題:網絡

  • 分區模型緊耦合存儲和計算,不是雲原生(Cloud Native)的設計。
  • 存儲模型過於簡單,對文件系統依賴太強。
  • IO 不隔離,消費者在清除 Backlog 時會影響其餘生產者和消費者。
  • 運維複雜,替換機器、服務擴容需從新均衡數據。

因而,咱們決定開始研發 Pulsar來解決消息隊列的擴展性問題。解決擴展性問題的核心思路是數據分片,Pulsar 從設計時就採用了分層分片式的架構,以提供更好的性能、可擴展性和靈活性。架構

下面咱們從技術角度來詳細解析 Apache Pulsar 的架構。框架

Pulsar 的分層架構

從數據庫到消息系統,大多數分佈式系統採用了數據處理和數據存儲共存於同一節點的方法。這種設計減小了網絡上的數據傳輸,能夠提供更簡單的基礎架構和性能優點,但其在系統可擴展性和高可用性上會大打折扣。運維

Pulsar 架構中數據服務和數據存儲是單獨的兩層:數據服務層由無狀態的 「Broker」 節點組成,而數據存儲層則由 「Bookie」 節點組成。分佈式

<center>圖 1 傳統單體架構 vs. Pulsar 存儲計算分層架構</center>

這種存儲和計算分離的架構給 Pulsar 帶來了不少優點。首先,在 Pulsar 這種分層架構中,服務層和存儲層都可以獨立擴展,能夠提供靈活的彈性擴容。特別是在彈性環境(例如雲和容器)中可以自動擴容縮容,並動態適應流量的峯值。而且, Pulsar 這種分層架構顯著下降了集羣擴展和升級的複雜性,提升了系統可用性和可管理性。此外,這種設計對容器是很是友好的,這使 得Pulsar 也成爲了流原平生臺的理想選擇。

Pulsar 系統架構的優點也包括 Pulsar 分片存儲數據的方式。Pulsar 將主題分區按照更小的分片粒度來存儲,而後將這些分片均勻打散分佈在存儲層的 「bookie」 節點上。這種以分片爲中心的數據存儲方式,將主題分區做爲一個邏輯概念,分爲多個較小的分片,並均勻分佈和存儲在存儲層中。這種架構設計爲 Pulsar 帶來了更好的性能,更靈活的擴展性和更高的可用性。

Pulsar 架構中的每層均可以單獨設置大小,進行擴展和配置。根據其在不一樣服務中的做用不一樣,可靈活配置集羣。對於須要長時間保留的用戶數據,無需從新配置 broker,只要調整存儲層的大小。若是要增長處理資源,不用從新強制配置存儲層,只需擴展處理層。此外,可根據每層的需求優化硬件或容器配置選擇,根據存儲優化存儲節點,根據內存優化服務節點,根據計算資源優化處理節點。

<center>圖 2 Apache Pulsar 系統架構</center>

而大多數消息隊列技術(包括 Apache Kafka)都採用單體架構,其消息處理和消息持久化(若是提供了的話)都在集羣內的同一個節點上。這種體系結構在大多數傳統的數據庫平臺以及 Hadoop 等大數據系統中也較爲常見,與昂貴的外部存儲陣列的常見替代方案相比,其設計目的在於將數據的計算與存儲放到同一臺機器上來處理,以減小網絡流量和訪問延遲,同時下降存儲成本。這種方法在小型環境中很容易部署,但在性能、可伸縮性和靈活性方面存在明顯問題。隨着固態磁盤的普遍使用,網絡帶寬的迅速提高以及存儲延遲的顯著下降,已經沒有必要採用單體架構進行這種權衡處理了。

接下來,咱們結合數據處理中各類不一樣的 IO 訪問模式來深刻了解 Pulsar 系統架構的優點。

IO 訪問模式的優點

流系統中一般有三種 IO 訪問模式:

  1. 寫(Writes):將新數據寫入系統中;
  2. 追尾讀(Tailing Reads):讀取最近寫入的數據;
  3. 追趕讀(Catch-up Reads):讀取歷史的數據。例如當一個新消費者想要從較早的時間點開始訪問數據,或者當舊消費者長時間離線後又恢復時。

和大多數其餘消息系統不一樣,Pulsar 中這些 IO 訪問模式中的每一種都與其餘模式隔離。在一樣 IO 訪問模式下,咱們來對比下 Pulsar 和其餘傳統消息系統(存儲和服務綁定在單個節點上,如 Apache Kafka)的不一樣。

傳統消息系統(圖 3 左側圖)中,每一個 Broker 只能利用本地磁盤提供的存儲容量,這會給系統帶來一些限制:

  1. Broker 能夠存儲和服務的數據量受限於單個節點的存儲容量。所以,一旦 Broker 節點的存儲容量耗盡,它就不能再提供寫請求,除非在寫入前先清除現有的部分數據。
  2. 對於單個分區,若是須要在多個節點中存儲多個備份,容量最小的節點將決定分區的最終大小。

<center>圖 3 傳統單體架構 vs. Pulsar 存儲計算分層架構</center>

相比之下,在 Apache Pulsar(圖 3 右側圖)中,數據服務和數據存儲是分離的,Pulsar 服務層的任意 Broker 均可以訪問存儲層的全部存儲節點,並利用全部節點的總體存儲容量。在服務層,從系統可用性的角度來看,這也有着深遠的影響,只要任一個 Pulsar 的 Broker 還在運行,用戶就能夠經過這個 Broker 讀取先前存儲在集羣中的任何數據,而且還可以繼續寫入數據。

下面咱們來詳細看一下在每種 IO 訪問模式下的架構優點。

在傳統消息系統架構中,一個分區的全部權會分配給 Leader Broker。對於寫請求,該 Leader Broker 接受寫入並將數據複製到其餘 Broker。如圖 4 左側所示,數據首先寫入 Leader Broker 並複製給其餘 followers。數據的一次持久化寫入的過程須要兩次網絡往返。

在 Pulsar 系統架構中,數據服務由無狀態 Broker 完成,而數據存儲在持久存儲中。數據會發送給服務該分區的 Broker,該 Broker 並行寫入數據到存儲層的多個節點中。一旦存儲層成功寫入數據並確認寫入,Broker 會將數據緩存在本地內存中以提供追尾讀(Tailing Reads)。

<center>圖 4 Writes 訪問模式對比</center>

如圖 4 所示,和傳統的系統架構相比,Pulsar 的系統架構並不會在寫入的 IO 路徑上引入額外的網絡往返或帶寬開銷。而存儲和服務的分離則會顯著提升系統的靈活性和可用性。

追尾讀

對於讀取最近寫入的數據場景,在傳統消息系統架構中,消費者從 Leader Broker 的本地存儲中讀取數據;在 Pulsar 的分層架中,消費者從 Broker 就能夠讀取數據,因爲 Broker 已經將數據緩存在內存中,並不須要去訪問存儲層。

<center>圖 5 Tailing Read 訪問模式對比</center>

這兩種架構只須要一次網絡往返就能夠讀取到數據。因爲 Pulsar 在系統中本身管理緩存中的數據,沒有依賴文件系統緩存,這樣 Tailing Reads 很容易在緩存中命中,而無需從磁盤讀取。傳統的系統架構通常依賴於文件系統的緩存,讀寫操做不只會相互競爭資源(包括內存),還會與代理上發生的其餘處理任務競爭。所以,在傳統的單片架構中實現緩存並擴展很是困難。追趕讀

追趕讀(Catch-up Reads)很是有趣。傳統的系統架構對 Tailing reads 和 Catch-up reads 兩種訪問模式進行了一樣的處理。即便一份數據存在多個 Broker 中,全部的 Catch-up reads 仍然只能發送給 Leader Broker。

Pulsar 的分層架構中歷史(舊)數據存儲在存儲層中。Catch-up 讀能夠經過存儲層並行讀取數據,而不會與 Write 和 Tailing Reads 兩種 IO 模式競爭或干擾。

三種 IO 模式放在一塊兒看

最有趣的是當你把這些不一樣的模式放在一塊兒時,也就是實際發生的狀況。這也正是單體架構的侷限性最使人痛苦的地方。傳統的消息系統架構中,全部不一樣的工做負載都被髮送到一箇中心(Leader Broker)位置,幾乎不可能在工做負載之間提供任何隔離。

然而,Pulsar 的分層架構能夠很容易地隔離這些 IO 模式:服務層的內存緩存爲 Tailing Reads 這種消費者提供最新的數據;而存儲層則爲歷史處理和數據分析型的消費者提供數據讀取服務。

<center>圖 6 三種 IO 模式對比</center>

這種 IO 隔離是 Pulsar 和傳統消息系統的根本差別之一,也是 Pulsar 可用於替換多個孤立系統的關鍵緣由之一。Apache Pulsar 的存儲架構讀、寫分離,能保證性能的一致性,不會引發數據發佈和數據消費間的資源競爭。已發佈數據的寫入傳遞到存儲層進行處理,而當前數據直接從 broker 內存緩存中讀取,舊數據直接從存儲層讀取。

超越傳統消息系統

上面討論了 Pulsar 的分層架構如何爲不一樣類型的工做負載提供高性能和可擴展性。Pulsar 分層架構帶來的好處遠遠不止這些。我舉幾個例子。

無限的流存儲

並行訪問流式計算中的最新數據和批量計算中的歷史數據,是業界一個廣泛的需求。

因爲 Pulsar 基於分片的架構,Pulsar 的一個主題在理論上能夠達到無限大小。當容量不足時,用戶只須要添加容器或存儲節點便可輕鬆擴展存儲層,而無需從新平衡數據;新添加的存儲節點會被當即用於新的分片或者分片副本的存儲。

Pulsar 將無界的數據看做是分片的流,分片分散存儲在分層存儲(tiered storage)、BookKeeper 集羣和 Broker 節點上,而對外提供一個統一的、無界數據的視圖。其次,不須要用戶顯式遷移數據,減小存儲成本並保持近似無限的存儲。所以,Pulsar 不只能夠存儲當前數據,還能夠存儲完整的歷史數據。

<center>圖 7 無限的流存儲</center>

數據查詢和數據分析

Pulsar 有能力存儲數據流的完整歷史記錄,所以用戶能夠在其數據上使用各類數據工具。Pulsar 使用 Pulsar SQL 查詢歷史消息,使用 Presto 引擎高效查詢 BookKeeper 中的數據。Presto 是用於大數據解決方案的高性能分佈式 SQL 查詢引擎,能夠在單個查詢中查詢多個數據源的數據。Pulsar SQL 容許 Presto SQL 引擎直接訪問存儲層中的數據,從而實現交互式 SQL 查詢數據,而不會干擾 Pulsar 的其餘工做負載。Pulsar 與 Presto 的集成就是一個很好的例子,以下是使用 Pulsar SQL 查詢的示例。

<center>圖 8 Presto 與 Apache Pulsar 的集成</center>

Pulsar 的周邊生態

批處理是對有界的數據進行處理,一般數據以文件的形式存儲在 HDFS 等分佈式文件系統中。流處理將數據看做是源源不斷的流,流處理系統以發佈/訂閱方式消費流數據。當前的大數據處理框架,例如 Spark、Flink 在 API 層和執行層正在逐步融合批、流做業的提交與執行,而 Pulsar 因爲能夠存儲無限的流數據,是極佳的統一數據存儲平臺。Pulsar 還能夠與其餘數據處理引擎(例如 Apache Spark 或 Apache Flink)進行相似集成,做爲批流一體的數據存儲平臺,這進一步擴展了 Pulsar 消息系統以外的角色。下圖展現了 Pulsar 的周邊生態。

<center>圖 9 Apache Pulsar 周邊生態</center>

總結

Apache Pulsar 是雲原生的分佈式消息流系統,採用了計算和存儲分層的架構和以 Segment 爲中心的分片存儲,所以 Apache Pulsar 具備更好的性能、可擴展性和靈活性,是一款能夠無限擴展的分佈式消息隊列。

Apache Pulsar 是一個年輕的開源項目,擁有很是多吸引人的特性。Pulsar 社區的發展迅猛,在不一樣的應用場景下不斷有新的案例落地。期待你們能和 Apache Pulsar 社區深刻合做,一塊兒進一步完善、優化 Pulsar 的特性和功能。

做者介紹:Sijie Guo,StreamNative 聯合創始人,Apache BookKeeper 和 Apache Pulsar PMC 成員和 Committer。以前是 Twitter 消息組的技術負責人,與他人共同建立了 Apache DistributedLog。加入 Twitter 以前,他曾在 Yahoo!從事推送通知基礎架構工做。

本文是「分佈式系統前沿技術」專題文章,目前該專題在持續更新中,歡迎你們保持關注👇

相關文章
相關標籤/搜索