天天看點

Apache BookKeeper 簡介

原作者:Sijie Guo

翻譯:StreamNative——Sijia

Apache BookKeeper 是企業級存儲系統,旨在保證高持久性、一緻性與低延遲。Pulsar 由雅虎研究院(Yahoo! Research)開發,旨在實作 Hadoop 分布式檔案系統(HDFS)NameNode 的高可用,在此之前,NameNode 不具備高可用特性,存在單點故障的問題。自 2011 年起,BookKeeper 開始在 Apache ZooKeeper 下作為子項目孵化,并于 2015 年 1 月作為頂級項目成功問世。在這四年間,Twitter、Yahoo、Salesforce 等公司使用 BookKeeper 存儲和服務重要資料,并支撐了許多不同場景。本文将簡要介紹 BookKeeper 的概念和相關術語。

背景介紹

BookKeeper 的開發者(Benjamin Reed、Flavio Junqueira、Ivan Kelly)憑借搭建 ZooKeeper 的經驗設計了一個靈活的系統,能夠支援多種工作負載。最初,BookKeeper 是分布式系統的預寫式日志(WAL)機制。現在 BookKeeper 已經發展成為支援多個企業級系統的基礎構模組化塊,如:Twitter 的 EventBus、雅虎的 Apache Pulsar 等。

BookKeeper 是什麼?

BookKeeper 是一種優化實時工作負載的存儲服務,具有可擴充、高容錯、低延遲的特點。根據我們多年的工作經驗,企業級的實時存儲平台應符合以下幾項要求:

  • 以極低的延遲(小于 5 毫秒)讀寫 entry 流
  • 能夠持久、一緻、容錯地存儲資料
  • 在寫資料時,能夠進行流式傳輸或追尾傳輸
  • 有效地存儲、通路曆史資料與實時資料

BookKeeper 的設計完全符合以上要求,并廣泛用于多種用例,例如為分布式系統提供高可用性或多副本(如 HDFS NameNode 節點、Twitter 的 Manhattan key-value 存儲);在單個叢集中或多個叢集間(多個資料中心)提供跨機器複制;為釋出/訂閱(pub-sub)消息系統(如 Twitter 的 EventBus、Apache Pulsar)提供存儲服務;為流工作存儲不可變對象(例如:檢查點資料的快照)等。

BookKeeper 的概念及術語

BookKeeper 複制并持久存儲日志流。日志流是形成良好序列的記錄流。

記錄

資料以不可分割記錄的序列,而不是單個位元組寫入 Apache BookKeeper 的日志。記錄是 BookKeeper 中最小的 I/O 單元,也被稱作位址單元。單條記錄中包含與該記錄相關或配置設定給該記錄的序列号(例如遞增的長數)。用戶端總是從特定記錄開始讀取,或者追尾序列。也就是說,用戶端通過監聽序列來尋找下一條要添加到日志中的記錄。用戶端可以單次接收單條記錄,也可以接收包含多條記錄的資料塊。序列号也可以用于随機檢索記錄。

日志

BookKeeper 中提供了兩個表示日志存儲的名詞:一個是 ledger(又稱日志段);另一個是 stream(又稱日志流)。

Ledger 用于記錄或存儲一系列資料記錄(日志)。當用戶端主動關閉或者當充當 writer 的用戶端當機時,正在寫入此 ledger 的記錄會丢失,而之前存儲在 ledger 中的資料不會丢失。Ledger 一旦被關閉就不可變,也就是說,不允許向已關閉的ledger 中添加資料記錄(日志)。

Apache BookKeeper 簡介

Stream(又稱日志流)是無界、無限的資料記錄序列。預設情況下,stream 永遠不會丢失。stream 和 ledger 有所不同。在追加記錄時,ledger 隻能運作一次,而 stream 可以運作多次。一個 stream 由多個 ledger 組成;每個 ledger 根據基于時間或空間的滾動政策循環。在 stream 被删除之前,stream 有可能存在相對較長的時間(幾天、幾個月,甚至幾年)。Stream 的主要資料保留機制是截斷,包括根據基于時間或空間的保留政策删除最早的 ledger。

Apache BookKeeper 簡介

Ledger 和 stream 為曆史資料和實時資料提供統一的存儲抽象。在寫入資料時,日志流流式傳輸或追尾傳輸實時資料記錄。存儲在 ledger 的實時資料成為曆史資料。累積在 stream 中的資料不受單機容量的限制。

命名空間

通常情況下,使用者在命名空間分類、管理日志流。命名空間是租戶用來建立 stream 的一種機制,也是一個部署或管理單元。使用者可以配置命名空間級别的資料放置政策。同一命名空間的所有 stream 都擁有相同的命名空間的設定,并将記錄存放在根據資料放置政策配置的存儲節點中。這為同時管理多個 stream 的機制提供了強有力的支援。

Bookies

Bookies 即存儲伺服器。一個 bookie 是一個單獨的 BookKeeper 存儲伺服器,用于存儲資料記錄。BookKeeper 跨 bookies 複制并存儲資料 entries。出于性能考慮,單個 bookie 上存儲 ledger 段,而不是整個 ledger。是以,bookie 就像是整個內建的一部分。對于任意給定 ledger L,內建指存儲 L 中 entries 的一組 bookies。将 entries 寫入 ledger 時,entries 就會跨內建分段(寫入 bookies 的一個分組而不是所有的 bookies)。

中繼資料

BookKeeper 需要中繼資料存儲服務,用來存儲 ledger 與可用 bookie 的相關資訊。目前,BookKeeper 利用ZooKeeper 來完成這項工作(除了資料存儲服務外,還包括一些協調、配置管理任務等)。

與 BookKeeper 互動

與 bookie 互動時,BookKeeper 應用程式有兩個主要作用:一個是建立 ledger 或 stream 以便寫入資料;另一個是打開 ledger 或 stream 以便讀取資料。為了與 BookKeeper 中兩個不同的存儲原語互動,BookKeeper 提供了兩個 API。

API 說明
Ledger API 較低級别的 API,允許使用者直接與 ledger 互動,極具靈活性,使用者可根據需要與 bookie 互動。
Stream API 較進階别、面向流的 API,通過 Apache DistributedLog 實作。使用者無需管理與 ledger 互動的複雜性,就可以與 stream 互動。

選擇使用哪個 API 取決于使用者對 ledger 語義設定的的粒度控制程度。 使用者也可以在單個應用程式中同時使用這兩個 API。

放在一起看

下圖即為 BookKeeper 的典型安裝示例。

Apache BookKeeper 簡介

上圖中的幾個注意事項:

  • 典型的 BookKeeper 安裝包括中繼資料存儲區(如 ZooKeeper)、bookie 叢集,以及通過提供的用戶端庫與 bookie 互動的多個用戶端。
  • 為便于用戶端的識别,bookie 會将自己廣播到中繼資料存儲區。
  • Bookie 會與中繼資料存儲區互動,作為資源回收筒收集已删除資料。
  • 應用程式通過提供的用戶端庫與 BookKeeper 互動(使用 ledger API 或 DistributedLog Stream API)
    • 應用程式 1 需要對 ledger 進行粒度控制,以便直接使用 ledger API。
    • 應用程式 2 不需要較低級别 ledger 控制,是以使用更加簡化的日志流 API。

總結