ZNBase 是開放原子開源基金會旗下的首個分佈式數據庫項目,由浪潮大數據團隊開源並捐贈。本文將介紹 ZNBase 的存儲架構,以及 ZNBase 技術團隊在其 KV 存儲引擎基礎上所作的優化實踐。git
ZNBase 總體存儲架構
云溪數據庫 ZNBase 採用分層架構,分爲計算層與存儲層,其整體架構以下圖所示:算法
在 OLTP 場景下,當開發人員向集羣發送 SQL 語句時,數據最終會以鍵值對 KV 的形式對存儲層進行讀寫。每一個 ZNBase 節點啓動時,至少會包含一個存儲節點。存儲層默認採用 KV 存儲引擎 RocksDB 負責存儲數據。每一個存儲實例均可能包含多個 Range,Range 是最底層的 KV 數據單元。Range 使用 Raft 一致性協議在集羣間進行復制。數據庫
爲了支持 HTAP 場景,ZNBase 的行存數據會經過 Raft Learner 同步到列存引擎,存儲層還擴展了矢量接口,經過列式存儲、計算下推、多節點並行計算知足業務應用的 AP 需求。另外存儲層還擴展了時序接口,能夠進行時序數據管理。緩存
接下來將着重介紹 ZNBase 存儲層架構中的 KV 存儲集羣。安全
RocksDB 引擎
ZNBase 的存儲層默認採用 RocksDB 來存儲數據。RocksDB 是由 Facebook 開源的高性能 KV 存儲引擎,讀寫數據能夠是任意字節流,其官方架構如圖所示,是一種 LSM-Tree 的實現:網絡
RocksDB 寫入流程以下:架構
一、以 batch 形式先順序寫入 WAL 文件用於故障恢復異步
二、再寫入內存中的 Memtable,Memtable 默認以 SkipList 形式存儲分佈式
三、Memtable 寫滿必定大小,默認 64MB,會轉爲不可變的 Immutable。工具
四、異步線程會將 Immutable 刷到磁盤 L0 層,變爲 SST 文件。
五、磁盤中使用多層來管理 SST 文件,經過合併過程將上層的 SST 文件落到下層,在合併過程當中會進行 GC 清理。
因而可知,RokcsDB 最新的數據是在內存或者上層的 SST 文件裏,因此讀取時優先讀取 Memtable 和 Immutable,再依此讀取各層文件。剛寫入的熱數據,能夠更快被讀到。另外 RocksDB 還提供了 Block Cache 進行讀緩存。
RocksDB 自己是一個 LSM-Tree 架構的高速 KV 存儲引擎,讀寫都會盡可能使用內存。RocksDB 提供原子的批量寫入、快照等功能,方便上層實現事務控制。基於 RocksDB 也支持高度安全的 AES 算法對存儲在磁盤上的數據加密,這樣即便磁盤被竊取,磁盤裏的數據也沒法被訪問。
因爲 RocksDB 採用 LSM-Tree 架構,一樣也存在必定的問題。好比在大數據量下有比較高的讀放大、寫放大、空間放大,性能衰減也比較厲害。爲了提升 ZNBase 在海量數據下的性能表現,ZNBase 團隊結合浪潮的硬件優點,開發了使用 SPDK 驅動在專用硬件 ZNS SSD 上進行軟硬件融合的存儲引擎;另外爲了更有效的利用內存,得到更快的讀寫速度,在大內存場景下也開發了準內存引擎的實現。
SPDK + ZNS SSD
固態硬盤(SSD)正在迅速擴展它在數據中心中的份額,相較於傳統存儲介質,新的閃存介質具備性能,耗電,機架空間等等方面的優點。
而浪潮自研的 ZNS SSD,在容量、壽命、成本、易用性、性能等方面實現飛躍式提高。ZNS SSD 即分區命名空間固態硬盤,能夠將 FTL(Flash Translation Layer)暴露給用戶以充分發揮 SSD 性能。ZNS 技術針對雲場景應用,主適用於大容量空間存儲的數據,例如高清視頻、圖像等。ZNBase 與 ZNS SSD 集成,經過智能數據部署能夠實現更好的空間運⽤,得到下降一倍以上的寫放大;文件可根據生命週期進行數據分區隔離,實現最低化垃圾回收;SST 文件可根據 LSM 分層進行清晰化冷熱數據分離,提高訪問效率;最小化的寫放大可提高讀取性能,減小合併成本和垃圾回收開銷;理論上,ZNS SSD 可帶來 15% 的性能提高和 10% 的成本收益。
因爲 SSD 自己的物理特性,其數據的訪問相較於傳統介質來講已經很是快了,而性能的瓶頸就是出在計算機與設備鏈接的接口和協議上面。舉個直觀的例子,咱們從北京乘飛機到美國,按照如今的飛行速度,在天上須要 13 個小時。這種狀況下,安檢的時間,過海關的時間,候機的時間,加起來 3 個小時,相對於總共的 13+3=16 個小時也不算長。設想若是如今飛機的飛行速度提升了 100 倍,飛行時間從 13 小時縮短至 10 分鐘,這時 3 個小時的地面手續流程就顯得很沒有效率了。換言之,在存儲硬件性能高速發展的今天,存儲軟件協議棧的性能和效率在存儲總體系統中的地位愈來愈重要。
SPDK ( Storage performance development kit ) 由 Intel 發起,提供了一組用於編寫高性能、可伸縮、用戶態存儲應用程序的工具和庫。SPDK 的基礎是用戶態、輪詢、異步、無鎖 NVMe 驅動,提供了從用戶空間應用程序到 NVMe 設備的零拷貝、高度並行的訪問。
NVMe 的全稱是 Non-Volatile Memory Express,若是翻譯過來就是非易失性內存主機控制器接口規範,是一種新型的存儲設備接口規範,用於定義硬件接口和傳輸協議,擁有比傳統 SATA SSD 的 AHCI 標準更高的讀寫性能。咱們能夠把 NVMe 看作一個硬件進步推進軟件革新需求的例子,隨着後續更快的存儲介質投入市場,這種推進力將更爲急迫。
SPDK 項目也是一種硬件進步推進軟件革新的產物,其目標就是可以把硬件平臺的計算、網絡、存儲的最新性能進展充分發揮出來。那麼 SPDK 是如何工做的?它超高的性能實際上來自於兩項核心技術:第一個是用戶態運行,第二個是輪詢模式驅動。
首先,將設備驅動代碼運行在用戶態,是和運行在「內核態」相對而言的。把設備驅動移出內核空間避免了內核上下文切換與中斷處理,從而節省了大量的 CPU 負擔,容許更多的指令週期用在實際處理數據存儲的工做上。不管存儲算法複雜仍是簡單,也不管進行去重(deduplication),加密(encryption),壓縮(compression),仍是簡單的塊讀寫,更少的指令週期浪費意味着更好的總體性能。
其次,傳統的中斷式 IO 處理模式,採用的是被動的派發式工做,有 IO 須要處理時就請求一箇中斷,CPU 收到中斷後才進行資源調度來處理 IO。舉一個出租車的例子作類比,傳統磁盤設備的 IO 任務就像出租車乘客,CPU 資源被調度用來處理 IO 中斷就像出租車。當磁盤速度遠慢於CPU 時,CPU 中斷處理資源充沛,中斷機制是能對這些 IO 任務應對自如的。這就比如是非高峯時段,出租車供大於求,路上老是有空車在掃馬路,乘客隨時都能叫到車。然而,在高峯時段,好比周五傍晚在鬧市區叫車(不用滴滴或者專車),經常是看到一輛車溜溜的近前來,然後卻發現後座已經有乘客了。須要等待多久,每每是不可預知的。相信你必定見過在路邊滯留,招手攔車的人羣。一樣,當硬盤速度上千倍的提升後,將隨之產生大量 IO 中斷,Linux 內核的中斷驅動式 IO 處理(Interrupt Driven IO Process)就顯得效率不高了。
而在輪詢模式驅動下,數據包和塊獲得迅速派發,等待時間最小化,從而達到低延時、更一致的延時(抖動變少)、更好的吞吐量的效果。
固然,輪詢模式驅動並非在全部的狀況下都是最高效的 IO 處理方式。對於低速的 SATA HDD,PMD 的處理機制不但給 IO 性能帶來的提高不明顯,反而浪費了 CPU 資源。
準內存引擎
除了採用 SPDK+ZNSSD 軟硬件結合的存儲引擎之外,爲了更有效的利用內存,得到更快的讀寫速度,ZNBase 在大內存場景下還開發了準內存引擎的實現。
準內存引擎開發的背景源自 RocksDB 的一些侷限性:
1.WAL 的單線程寫模式,不能充分發揮高速設備的性能優點;
2.讀操做時,有可能須要查找 level 0 層的多個文件及其餘層的文件,這也形成了很大的讀放大。尤爲是當純隨機寫入後,讀幾乎是要查詢 level0 層的全部文件,致使了讀操做的低效。
3.針對第 2 點問題,RocksDB 中依據 level 0 層文件的個數來作前臺寫流控及後臺合併觸發,以此來平衡讀寫的性能。這又致使了性能抖動及不能發揮高速介質性能的問題。
4.合併流程難以控制,容易形成性能抖動及寫放大。
近年來,隨着動態隨機存儲器(DRAM)容量的上升和單位價格的降低,使大量數據在內存中的存儲和處理成爲可能。相對於磁盤,內存的數據讀寫速度要高出幾個數量級,將數據保存在內存中相比從磁盤上訪問可以極大地提升應用的性能。
針對這一理念,準內存引擎設計原則以下:
1.數據儘可能存放在內存中,充分利用內存的讀寫性能。
2.基於索引與數據分離存儲的思想,索引常駐內存。數據能夠根據內存容量,將部分存儲到持久化存儲設備中。
3.提高 cpu cache 命中率,經過數據塊的重構(拆解、擴容、縮容)將 Key 相鄰的 KV 數據在內存空間中也相鄰,以提高 key 值遍歷的速度。
4.使用異步落盤機制,保證平滑的 IO 速率,消除 IO 瓶頸。
基於 ART 索引的檢索機制,保證數據訪問速度。ART 算法使用基於樂觀鎖的的同步機制,讀操做不阻塞,寫操做使用版本信息的 CAS 原子操做以及重試機制。
因爲已經過 Raft Log 實現數據的故障恢復,能夠去除 WAL 寫入過程。
準內存引擎整體處理流程以下:
1. 新插入的數據存放在 內存臨時區中的 Memtable 以及 Immutable 中。
2. 異步線程 Mem-Flush 將 Immutable 中的數據轉存到內存存儲區。
3. 內存存儲區會盡量佔用更多的內存空間,用於存放數據。使用 ART 算法索引這些數據。
4. 內存存儲區內存空間即將不足時,啓用 L1-Flush 後臺線程清理內存存儲區中的數據。
5. L1-Flush 後臺線程,將該內存存儲區中全部的 KV 數據以及範圍刪除數據進行落盤。因爲數據量大且數據有序,所以,直接落盤到 L1 層。落盤前須要保證 L1 層無文件。落盤完成後,建立 L1 層文件向下合併的任務。
準內存引擎採用 ART 算法做爲主索引的實現,能夠進行快速的範圍查找,輔助使用 Hash 索引方便進行 Get 查詢。之因此使用 ART 算法,是由於其在讀寫方面性能均優於 B+樹、紅黑樹、二叉樹,可比肩哈希表,而 ART 算法比哈希表的優點是 ART 算法可按順序遍歷全部數據。
參見論文:The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases
總結
本文爲你們介紹了 ZNBase 基於 RocksDB 的存儲引擎架構,以及 ZNBase 團隊針對 RocksDB 的侷限性,經過開發軟硬件結合的 SPDK+ZNS SSD 存儲引擎、大內存場景下的準內存引擎,大大提升了存儲引擎的讀寫性能。
關於 ZNBase 的更多詳情能夠查看:
官方代碼倉庫:https://gitee.com/ZNBase/zn-kvs
ZNBase 官網:http://www.znbase.com/
對相關技術或產品有任何問題歡迎提 issue 或在社區中留言討論。同時歡迎廣大對分佈式數據庫感興趣的開發者共同參與 ZNBase 項目的建設。
聯繫郵箱:haojingyi@inspur.com