Pulsar 入門實戰(2)--特性及架構

且行且码發表於2024-08-25

本文主要介紹 Pulsar 的特性及架構,對應的 pulsar 版本為 3.3.x。

1、Pulsar 特性

  • Pulsar例項原生支援多個叢集,並且在叢集之間實現了無縫的地理複製訊息。
  • 極低的釋出和端到端延遲。
  • 無縫擴充套件至超過一百萬個主題。
  • 簡單的客戶端 API,支援 Java、Go、Python 和 C++ 語言。
  • 多種訂閱型別(獨佔、共享和故障轉移)。
  • 透過Apache BookKeeper提供的持久化訊息儲存,保證訊息傳遞。無伺服器輕量計算框架Pulsar Functions提供流原生資料處理能力。
  • 無伺服器聯結器框架Pulsar IO基於Pulsar Functions構建,使得資料在Apache Pulsar內外的移動更加容易。
  • 分層儲存在資料老化時將其從熱/溫儲存解除安裝到冷/長期儲存(例如S3和GCS)。

2、架構

2.1、架構概述

在最高階別上,Pulsar 例項由一個或多個 Pulsar 叢集組成。例項內的叢集間會同步資料。

一個 pulsar 包含以下元件:

  • 一個或多個 broker, 負責處理和負載均衡來自生產者的訊息,並將訊息分派給消費者,與 pulsar 配置儲存通訊以處理各種協調任務,將訊息儲存在 BookKeeper 例項(又稱 bookies)中,依賴於 ZooKeeper 叢集執行某些任務等。
  • 一個或多個 bookie 組成的 BookKeeper 叢集,負責處理訊息的持久儲存。
  • 一個 ZooKeeper 叢集,負責處理 pulsar 叢集之間的協調任務。

下圖表示了一個 pulsar 叢集:

在更廣泛的例項級別,一個稱為配置儲存的例項級 ZooKeeper 叢集處理涉及多個叢集的協調任務,例如地理複製。

2.2、Brokers

broker 是一個無狀態元件,主要負責執行另外兩個元件:

  • 一個 HTTP 伺服器,暴露 REST API,用於管理任務和生產者與消費者的主題查詢。生產者連線到 broker 以釋出訊息,消費者連線到 broker 以消費訊息。
  • 一個排程程式,是一個基於自定義二進位制協議的非同步 TCP 伺服器,用於所有資料傳輸。

為了提高效能,訊息通常會從受控分散式日誌快取中分派,除非積壓超過了快取大小。如果積壓量過大,超出了快取的處理能力,broker 將從 BookKeeper 中讀取條目。

最後,為了支援全域性主題的地理複製,broker 管理複製器,這些複製器追蹤本地區釋出的條目,並使用 Pulsar Java 客戶端將它們重新發布到遠端區域。

2.3、叢集

一個 pulsar 例項包括一個或多個 pulsar 叢集。叢集本身由以下組成:

  • 一個或多個 broker
  • 用於叢集級配置和協調的 ZooKeeper 叢集
  • 用於訊息持久儲存的 bookie 集合

可以透過地理複製在叢集間進行資料複製。

2.4、後設資料儲存

Pulsar 的後設資料儲存維護著整個 Pulsar 叢集的所有後設資料,例如主題後設資料、模式、broker 負載資料等。Pulsar 使用 ZooKeeper 來儲存後設資料、進行叢集配置和協調。Pulsar 的後設資料儲存可以單獨部署在一個 ZooKeeper 叢集上,也可以部署在已有的 ZooKeeper 叢集上。可以使用同一個 ZooKeeper 叢集來儲存 Pulsar 的後設資料和 BookKeeper 的後設資料。如果想要部署 broker 以連到現有的 BookKeeper 叢集 ,那麼需要分別為 Pulsar 後設資料儲存和 BookKeeper 後設資料儲存部署獨立的 ZooKeeper 叢集。

Pulsar 還支援更多的後設資料後端服務,包括 etcd 和 RocksDB(僅適用於單機的 Pulsar)。

在 Pulsar 例項中:

  • 配置儲存中儲存了租戶、名稱空間及其他需要全域性一致性的實體配置。
  • 每個叢集都有自己的本地 ZooKeeper 叢集,用於儲存叢集特定的配置和協調資訊,例如哪些 broker 負責哪些主題、所有權後設資料、broker 負載報告、BookKeeper ledger 後設資料等。

2.5、配置儲存

配置儲存是一個 ZooKeeper 叢集,用於處理與配置相關的任務,並維護 Pulsar 例項的所有配置,例如叢集、租戶、名稱空間、分割槽主題相關的配置等。一個 Pulsar 例項可以有一個本地叢集、多個本地叢集或多個跨區域叢集。因此,配置儲存可以在 Pulsar 例項中的多個叢集之間共享。配置儲存可以使用單獨的 ZooKeeper 叢集,也可以使用現有的 ZooKeeper 叢集。

2.6、持久儲存

Pulsar 為應用程式提供了可靠的訊息傳遞保證。如果訊息成功到達 pulsar broker,它將被傳遞給其預期的目標。
這種保證要求非確認的訊息在持久化儲存中保留,直到傳遞給消費者並收到確認。這種訊息傳遞模式通常稱為持久化訊息傳遞。在 Pulsar 中,所有訊息的 N 個副本都被儲存並同步到磁碟上,例如,在兩臺伺服器上透過映象 RAID 卷儲存 4 個副本。

2.6.1、Apache BookKeeper

Pulsar使用 Apache BookKeeper 進行持久化訊息儲存。BookKeeper 是一個分散式的預寫式日誌(WAL)系統,為 Pulsar 提供了幾個關鍵優勢:

  • 它使 Pulsar 能夠利用許多獨立的日誌(ledger)。隨著時間的推移,可以為主題建立多個 ledger。
  • 它為處理條目複製的順序資料提供非常高效的儲存。
  • 它在各種系統故障情況下保證 ledger 的讀一致性。
  • 它能夠在 bookies 之間均勻分配 I/O。
  • 它在容量和吞吐量上具有水平可擴充套件性。透過向叢集新增更多的 bookie,可以立即增加容量。
  • Bookies 被設計為處理數千個 ledger 的併發讀寫。透過使用多個磁碟裝置--一個用於日誌,另一個用於一般儲存--bookies 可以將讀操作與有延遲的寫操作隔離開來

除了訊息資料外,BookKeeper 還持久儲存遊標。遊標是消費者的訂閱位置。BookKeeper 使得 Pulsar 能夠以可擴充套件的方式儲存消費者的位置。

目前,Pulsar 支援持久化訊息儲存。這體現在所有主題名稱中的"persistent"一詞。以下是一個示例:

persistent://my-tenant/my-namespace/my-topic

Pulsar 還支援臨時的非持久化訊息儲存。

下圖為 brokers 和 bookies 之間的互動示意圖:

2.6.2、Ledgers

ledger 是一種僅追加的資料結構,只有一個寫入者,它被分配給多個 BookKeeper 儲存節點--bookie。ledger 條目會被複制到多個 bookie。ledger 本身具有非常簡單的語義:

  • Pulsar broker 節點可以建立 ledger,向 ledger 追加條目,並關閉 ledger。
  • 一旦 ledger 被關閉--無論是顯式關閉還是因為寫入程序崩潰--它只能以只讀模式重新開啟。
  • 最後,當不再需要 ledger 中的條目時,可以從系統中(所有 bookies 中)刪除整個 ledger。

Ledger 讀一致性

Bookkeeper 的主要優勢在於,在發生故障時,它保證 ledger 的讀一致性。由於 ledger 只能由單個程序寫入,該程序可以非常高效地追加條目,無需獲得共享鎖。在發生故障後,ledger 將經歷恢復過程,該過程將最終確定 ledger 的狀態,並確定最後提交的條目。在那之後,所有讀取 ledger 的操作都保證能看到完全相同的內容。

託管 ledgers

鑑於 Bookkeeper ledger 提供了單一的日誌抽象,因此在 ledger 之上開發了一個名為"managed ledger"的庫,它代表了單個主題的儲存層。託管 ledger 表示訊息流的抽象,單一的寫入者在流的末尾不斷追加訊息;並且有多個消費者遊標在消費這個流,每個遊標都有其關聯的位置。

在內部,單個託管 ledger 使用多個BookKeeper ledger 來儲存資料。有兩個理由使用多個 ledger:

  • 在發生故障後,ledger 不再可寫,需要建立一個新的 ledger。
  • 當所有遊標消費完 ledger 中的訊息後,可以刪除該 ledger。這允許定期滾動 ledger。

2.6.3、Journal 儲存

在 BookKeeper 中,Journal 檔案包含 BookKeeper 事務日誌。在對 ledger 進行更新之前,Bookie 需要確保將描述更新的事務寫入持久(非易失性)儲存。一旦 Bookie 啟動或者舊的 journal 檔案大小達到了閾值(透過引數 journalMaxSizeMB 配置),就會建立一個新的 journal 檔案。

2.7、Pulsar 代理

Pulsar 客戶端與 Pulsar 叢集進行互動的一種方式是直接連線到 Pulsar broker。然而,在某些情況下,這種直接連線不可行或不可取,因為客戶端無法直接訪問 broker 地址。例如,如果在雲環境、Kubernetes 或類似的平臺上執行 Pulsar,那麼直接連線客戶端到 broker 的方式可能是不可行的。

Pulsar 代理透過充當叢集中所有 broker 的單一閘道器,提供瞭解決這個問題的方案。如果執行 Pulsar 代理(再次強調,這是可選的),客戶端將透過代理與 Pulsar 叢集連線,而不是直接與 broker 通訊。

為了效能和容錯性,請根據需要執行多個 Pulsar 代理例項。

在架構上,Pulsar 代理從 ZooKeeper 獲取其所需的所有資訊。在啟動代理時,只需提供後設資料儲存和配置儲存的地址。以下是一個示例:

bin/pulsar proxy \
    --metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181 \
    --configuration-metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181

Pulsar 代理的詳細說明,可參閱 Pulsar 代理管理文件

關於 Pulsar 代理的一些重要事項:

  • 客戶端使用 Pulsar 代理時無需提供任何特定的配置。不需要更新現有應用程式的客戶端配置,除服務 URL 的 IP 改變了(例如,在 Pulsar 代理上執行負載均衡器)。
  • Pulsar 代理支援 TLS 加密和 mTLS 身份驗證。

2.8、服務發現

服務發現是一種機制,它使客戶端能夠使用單個 URL 與整個 Pulsar 例項進行互動。

如果願意,可以使用自己的服務發現系統。如果使用自己的系統,只有一個要求:當客戶端對一個地址發起 HTTP 請求,比如 http://pulsar.us-west.example.com:8080 時,需要將客戶端重定向到叢集中的某個活躍 broker,可以透過 DNS、HTTP 或 IP 重定向,或者其他方式實現。

下圖說明了 Pulsar 的服務發現:

在這個圖示中,Pulsar 叢集透過一個單一的 DNS 名稱進行定址:pulsar-cluster.acme.com。Python 客戶端可以這樣訪問這個 Pulsar 叢集:

from pulsar import Client

client = Client('pulsar://pulsar-cluster.acme.com:6650')

注意:在 Pulsar 中,每個主題僅由一個 broker 處理。客戶端對主題的初始讀取、更新或刪除請求可能會傳送到不是該主題所有者的 broker。如果 broker 無法處理此主題的請求,它會將請求重定向到適當的 broker。

參考:https://pulsar.apache.org/docs/3.3.x/concepts-architecture-overview/

相關文章