博文推薦|BookKeeper - Apache Pulsar 高可用 / 強一致 / 低延遲的儲存實現

語言: CN / TW / HK

本文轉自:DataFunTalk,分享嘉賓:翟佳,StreamNative 聯合創始人
編輯整理:張曉偉 美團點評

導讀:多數讀者們瞭解 BookKeeper 是通過 Pulsar,實際上 BookKeeper 在資料庫和儲存場景都有著非常廣泛的應用。BookKeeper 是 Pulsar 的底層儲存,Pulsar 有著廣泛資料入口,Pulsar 跟 Kafka 及各類 MQ(RabbitMQ、ACTIVEMQ)的較大區別是 Pulsar 是統一的雲原生訊息流平臺,不但是分散式系統,而且做了存算分離,可以讓使用者在雲的環境下,體驗到雲原生的優勢,例如隨意擴縮容、資料靈活遷移複製等。希望通過本文,讓大家對 Pulsar 底層的 BookKeeper 有更深入的瞭解。

(點選上方圖片觀看回顧視訊)

今天的介紹會圍繞下面四點展開:

  • • BookKeeper 的簡介

  • • BookKeeper 的特性

  • • BookKeeper 儲存介質的演進

  • • BookKeeper 的社群資源

BookKeeper 的簡介

業務場景需求的統一

Pulsar 裡有很重要的概念是“統一”,這個統一的特性是由 BookKeeper 支援實現的。這裡的統一是指需求的統一,在訊息場景下,使用者場景分兩類:

第一類是線上業務場景,例如 1984 年誕生的 IBM MQ 到現在的各類開源 MQ 解決的是線上業務場景,這些 MQ 的服務質量會對業務服務質量有著直接的影響,所以這類需求對資料質量,例如對資料永續性、資料延遲、消費模型的靈活性有較強的要求。

第二類是大資料場景,例如 2010 年左右隨著實時計算的廣泛使用,Kafka 的這種高頻寬和高吞吐使用需求。

由於面向場景不同、技術棧不同,這兩種場景在業務上又同時存在,給業務帶來不同的基礎設施 API、不同的使用方式、不同系統的運維成本等問題。所以 Pulsar 針對這些問題,做了兩層 API 的統一:既相容 MQ 的併發消費模型,提供比較好的服務質量,同時通過底層儲存層抽象,可以提供很高的吞吐和頻寬,這就是我們要介紹的 Apache BookKeeper 專案。

Apache BookKeeper 簡介

很多服務裡都有日誌,例如 MySQL 的 binlog 和 HDFS 的 namenode 的 editlog,都是對日誌的一個抽象,而 BookKeeper 就是把這個抽象變成了一個分散式的服務,擺脫了對單機容量瓶頸的限制,把日誌變成了可無限擴充套件的服務。BookKeeper 使用 packet source 協議和 ZooKeeper 的 zap 協議,通過 log append only 的方式實現了低延遲和高吞吐。在 APCP 裡選擇 CP,而 availability 是通過多副本併發的方式提供高可用,BookKeeper 有著低延遲、高吞吐、持久化、資料的強一致性、服務的高可用、單節點可以儲存很多日誌、IO 隔離等優勢,針對這些特性在後文會展開介紹。

BookKeeper 的誕生

BookKeeper 也是 Apache 的一個專案,同樣是由雅虎捐獻誕生,原本是為了應對雅虎開源 HDFS 裡元資料儲存的需求。

下圖是位元組跳動技術文章的一個圖,主要是呈現在位元組跳動如何用 BookKeeper 支撐元資料服務,支撐起 EB 級別的 HDFS 叢集。這個叢集 DN 有好幾萬臺,需要很多 NameNode,就需要一個可以保障 active/standby/observer NameNode 之間強一致性的日誌服務,單機容量瓶頸下很難支撐這麼大的體量時,引入了一個分散式的日誌服務,這就是 BookKeeper 誕生的場景。隨著 HDFS 大規模的問題開始出現之後,BookKeeper 成為了 HDFS 在 HA 上的剛需需求,例如在 EMC 內部的 HDFS 叢集,也是用的 BookKeeper 來做 NameNode 的 editlog 服務。BookKeeper 是一種分散式場景下很常見的複製狀態機的實現(通過複製 log,保持各個節點狀態機的同步,A 節點持久化 log 後,把 log 同步到 B 節點,在 B 節點進行 log 的一個重放,讓 B 節點達到跟 A 節點一樣的一個狀態)。由於在 HDFS 場景中,儲存的只是 NN 的變更日誌,所以算是元資料的元資料,對資料一致性、對吞吐、對時延的要求自然極高。

BookKeeper 使用案例

BookKeeper 也有侷限性,是 append only 的一個抽象變成了分散式服務,相對而言比較底層。所以使用者多是一些比較大的網際網路公司或其他有大資料量的需求的使用者,這些使用者會在 BookKeeper 之上做一些二次開發,例如 Pulsar 在 BookKeeper 之上做了一層 broker 服務,對 BookKeeper 的每個分片做一些管理然後將其作為資料的儲存服務。

類似的還有 Twitter 和 Salesforce。Twitter 的技術棧是構建在實時計算上的,在 Twitter 內部,BookKeeper 是作為很重要的基礎設施,不但有類似 Pulsar 的服務 eventbus,還有其他使用場景例如搜尋、廣告、Stream computing, 以及作為類似 KV 儲存的 Manhattan Database 的元資料服務,這些場景都用到了 BookKeeper。在規模上,Twitter BookKeeper 有兩個叢集,每個叢集約有 1500 個節點,每天有 17PB 的資料,每秒 1.5 萬億的 records。而在 Salesforce 的使用背景,是 Salesforce 想去掉對 Oracle 的依賴,所以自研了類似 Amazon Aurora 的 NewSQL Database,其內部很多跟元資料相關或有一致性要求的服務都是通過 BookKeeper 來滿足的,並且也有部分後端場景將 BookKeeper 作為儲存服務去用。

BookKeeper 的特性

BookKeeper 基本概念

Ledger

可以理解為 BookKeeper 是會計,Ledger 是賬本,每個賬本是記錄資訊的一個單元,寫完之後轉為 closed 狀態(只讀),最新的賬本是開啟狀態(openLedger),以 append only 的方式持續儲存資料。

Fragment

可以理解為 BookKeeper 內部維護的一個以 append only 的方式新增的資料組。

Fragment 之下就是使用者以 append only 的方式追加的一條條資料。

BookKeeper 的節點對等架構

openLedger 時有 3 個引數:Ensemble 選擇幾個節點儲存這個賬本,Write Quorum 控制資料寫幾個副本(併發寫,不同於 Kafka 或 HDFS,BookKeeper 沒有資料節點之間主從同步的關係,把資料同步的協調者從服務端移到了客戶端),Ack Quorum 控制等幾個副本返回 ack。

以下圖為例 openLedger(5,3,2),在儲存這個賬本時,選擇了 5 個節點,但是隻寫 3 個副本,等 2 個副本來返回 ack。第一個引數一般可用於調整併發度,因為寫 3 個副本是通過輪轉的方式寫入,例如第 1 個 record 是寫 1-3 節點,第 2 個 record 寫 2-4 節點,第 3 個 record 寫 3-5 節點,第 4 個 record 寫 4-5 和 1 節點這樣輪轉。這種方式即便 3 個副本,也可以把 5 個節點都用起來。

這幾個引數便捷的特性可讓使用者通過機架感知、機房感知、resource 感知等各種方式進行靈活設定。當選好節點後節點之間的排序就已完成,每個 record 會帶個 index,index 和節點已有繫結關係,例如 index 為 1 的,都放在 123 上,為 2 的都放在 234 上。通過這種方式可以讓我們知道每個節點存了哪些訊息,當某個節點宕機,根據這個節點的位置資訊,把對應 record 還在哪些節點上有副本的資訊找出來進行多對多的恢復。這麼做的另一個好處是不用再維護元資料資訊,只需要有每個節點記錄 index 資訊,在 openLedger 時記錄好每個節點的順序即可。

openLedger(5,3,2)資料儲存結構就是下圖中右邊的結構,如果選擇 Ensemble=3,Write Quorum=3,資料儲存結構就是下圖左邊的結構:

綜上,使用者可以通過 Ensemble 來調整讀寫頻寬,通過 Write Quorum 調整強一致性的控制,通過 Ack Quorum 權衡在有較多副本時也可以有較低的長尾時延(但一致性就可能有一定的損失)。

BookKeeper 可用性

讀的高可用

讀的訪問是對等的,任意一個節點返回就算讀成功。這個特性可以把延遲固定在一個閾值內,當遇到網路抖動或壞節點,通過延遲的引數避障。例如讀的延遲時間 2ms,讀節點 3 超過 2ms,就會併發地讀節點 4,任意一個節點返回就算讀成功,如下圖 Reader 部分。

寫的高可用

在 openLedger 時會記錄每個節點的順序,假如寫到 5 節點宕機,會做一次元資料的變更,從這個時間開始,先進行資料恢復,同時新的 index 中會把 5 節點變為 6 節點,如下圖 x 節點替換 5 節點:

BookKeeper 一致性

BookKeeper 底層節點對等設計讓寫入資料的 Writer 成為了協調者,Writer 來儲存資料是否儲存成功的狀態,例如節點是否出現問題、副本夠不夠、切換 Fragment 時要不要做資料恢復、在寫入過程中出現宕機時,通過 fencing 的方式防止腦裂等。所以,Writer 維護了 2 個 index:LastAddPushed 和 LastAddConfirmed。

LastAddPushed 會隨訊息 ID 遞增,LastAddConfirmed 則記錄最後一個連續的訊息成功寫入了(例如 Ack Quorum 為 2,有 2 個成功返回了即為成功),但因為返回順序不一定與訊息順序一致,例如 123 個訊息,3 的訊息先返回了,2 的還未返回,按連續的規則就是 2 不是 3。

BookKeeper 與 Raft 的對比

在底層原理上,Raft 與 BookKeeper 有很多類似的地方,Raft 每個資料寫入的組織形式是 term,跟 BookKeeper 的 segment 類似,每個 term 也會選擇一組節點儲存資料,然後不斷往後追加資料,通過資料節點之間的協同保證資料一致性。

在資料結構上,Raft 在儲存資料時有 Entry,Entry 除了帶本身的 index 還會帶上 last committed index,與 BookKeeper 中的 LastAddConfirmed 較為類似,只是 BK 是通過 Writer 來協調資料在不同節點的一致性,Raft 有 leader 來協調資料在不同節點的一致性。

BookKeeper 的 IO 讀寫分離

下圖是每個資料節點的資料流轉過程,資料寫入時,Writer 通過 append only 方式寫入到 Journal,Journal 在把資料寫到記憶體的同時會按一定頻率(預設 1ms 或 500 byte)把資料持久化到 Journal Device 裡,寫完後會告訴 Writer 這個節點寫入成功了(持久化到磁碟是預設配置)。

Journal 在資料寫入時有寫到記憶體中,接下來在記憶體中做排序(用於解決如果按寫的順序讀會導致分割槽隨機性強的問題),然後把資料刷到資料盤中。讀的時候,如果讀最新的資料,可以直接從記憶體裡返回,如果讀歷史資料,也只去讀資料盤,不會對 Journal Device 寫入有影響。這樣針對有讀瓶頸或寫瓶頸的使用者,可以把 Journal Disk 或 Ledger Disk 換成 SSD 盤,提升效能,並且防止讀寫的互相干擾。

BookKeeper 的儲存介質演變

BookKeeper 的 Disk 演進

在演進過程中,因為順序讀的情況比較多,所以讀的部分變化不大,但在寫的這部分經歷了 HDD 到 SSD 再到 NVMe SSD,再到現在部分使用者換成了 Intel 的 PMem 的過程(如下圖所示)。在換到 NVMe SSD 時,部分使用者通過多目錄的方式可以把 SSD 的 IO 頻寬打的很滿。

PMEM 在 BookKeeper 上的應用

PMem 的特性非常匹配 Journal Disk,單塊 PMem 可以達到 3-4GB 的頻寬,不但能提供高頻寬吞吐而且可持久化。PMem 容量相比 SSD 比較小、相比記憶體又比較大,在剛推出時單條 128GB,有著 GB 級別的吞吐和 ns 級別的延遲。

高吞吐低容量的 PMem 非常適合 Journal 持久話刷盤的需求,例如宕機後,需要對沒刷到磁碟的這部分資料做恢復,需要 Journal 做 replay log 重放,由於只是增量日誌而非全量資料,所以並不需要很大的容量,正好和 PMem 容量不大相匹配。而且,PMem 的壽命會比 SSD 的壽命長一些,例如在每天同樣寫入量下 SSD 可能只能用 1 年而 PMem 預計可以使用 4-5 年。

雅虎(現在是 Verizon Media)有實際通過 PMEem 優化 BookKeeper 的案例,在只增加 5%的單機成本情況下提升了 5 倍的頻寬吞吐和低於 5ms 的時延保障(BookKeeper 社群與 Intel 正在合作做效能測試,預計未來會產出白皮書說明)。

在雅虎案例中用 10 臺 Pulsar(底層是用 PMem 做 Journal Disk 的 BookKeeper)替換了 33 臺 Kafka,比原 Kafka 方案成本降低了一半,產出的對比結果如下:

社群資源

團隊構成

由 Apache Pulsar 核心研發團隊創立,同時有 Apache Pulsar 和 Apache BookKeeper 專案管理委員會(PMC)主席,有 6 名 Apache Pulsar PMC 成員和 3 名 Apache BookKeeper PMC 成員,有約 20 名 Apache Committer。

里程碑

公司成立於 2019 年,2020 年釋出商業化產品 StreamNative Cloud,目前有 50+付費客戶,覆蓋金融、IoT、網際網路、製造多個行業。

優勢

是社群和程式碼的構建維護者,有全球最專業的 Pulsar 設計開發、運維、管理團隊的 7*24 小時服務,提供開箱即用的雲服務和諮詢培訓服務。


相關閱讀


 Apache Pulsar 

  掃描下方二維碼回覆關鍵詞“BookKeeper
加入 Pulsar_Storage SIG 小組

,立即觀看回顧視訊

本文分享自微信公眾號 - ApachePulsar(ApachePulsar)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

「其他文章」