博文推薦|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源創計劃”,歡迎正在閲讀的你也加入,一起分享。

「其他文章」