Pliops XDP(Extreme Data Processor)数据库存储设计的新型加速硬件
文章目錄
- 0 前言
- 1 核心問題
- 1.1 引擎的各方面性能受限于數據結構的選擇
- 1.2 壓縮功能 導致的CPU瓶頸
- 1.3 Crash-safe 崩潰異常的無奈選擇
- 1.4 當前主流 加速硬件 較難滿足存儲性能提升的要求
- 2 XDP 設計原則
- 2.1 數據結構上的優化
- 2.2 解決 壓縮引入的CPU消耗
- 2.3 異常恢復的設計
- 2.4 易于集成
- 3 XDP 基本架構
- 4 總結
0 前言
以色列 公司 Pliops 2021年 VLDB上發表了篇The End of Moore’s Law and the Rise of The Data Processor,介紹他們在 計算硬件領域的新方案。
ps : 這個方案并不是 最近推出的 內核網絡協議棧的優化 Express Data Path,雖然名字一樣。
其雖然主推的是計算能力(類似的硬件有FPGA/GPU),但是他們做出了對存儲工業界來說更為友好的解決方案,那就是 將計算+I/O 整合到了一塊,對外提供一個完整的使用方案。這對數據庫應用來說,是一個值得嘗試的方向。
本文主要是一個粗略的整體方案的介紹,幫助大家快速了解 XDP 解決的核心問題 、 主要的設計原則 、基本的架構。
更多的細節可以參考前面提到的論文。
XDP 的方案設計主要是為數據庫存儲領域做的,單純對比 其 和其他加速硬件的計算能力是沒有意義的。
先看看 各個數據庫引擎底座近些年遇到的一些問題。
1 核心問題
如今我們的計算機硬件 已經不能按照摩爾定律持續增加性能了,不論是計算芯片 還是 存儲硬件上的芯片 ,硅基晶體管的大小受限于科技水平已經不能再小了,要不然為什么 Flash-ssd 從 SLC --> TLC --> QLC 這種方式來增加存儲容量 而不是讓 SLC 更小 來為一個block 放更多的slc(畢竟SLC 性能/準確性更可控 ) 。
當然,也可以更換存儲介質,比如 PCM 為存儲單元的 3D XPoint,但是成本扛不住啊,而且最后也得受限于微觀工藝上的發展。
計算芯片同樣的原理,物理CPU上如果能放更多的晶體管,那意味著每一個時鐘周期可以參與計算的單元更多,性能自然就上去了。
硬件的微觀層面已經到瓶頸了,那這一些方向的探索只能靠科學家去探索了,所以應用層面還需要考慮更多能夠保持性能增加的可行方向。硬件加速卡就是一個方向,解放CPU的算力,自己帶著自己的 memory/CU 甚至電容器 加入到服務器大家庭,我們的 FPGA / GPU 就在這個大背景下出現了。
那 Pliops XDP 看到了計算領域 已經比較成熟了, 但是計算硬件和存儲硬件的結合還是有很多可以做的方向(存儲 既有 計算密集型 也有 IO 密集型的場景),他們細致分析了存儲領域的一些痛點,做出了XDP。
1.1 引擎的各方面性能受限于數據結構的選擇
現如今的存儲引擎 主題數據結構形態 不論是LSM-tree/ B-tree/ Hash 都是 index + log,內存中有一部分的數據索引用來加速讀性能,內存累積了一部分寫入數據會 Flush 到磁盤存儲中。
- LSM-tree 引擎的 內存組件設計 是為了提升寫性能,將上層的隨機寫轉化為內存的有序結構從而形成順序寫;卻犧牲了一部分讀性能(Rocksdb 為了提升讀性能做了太多的組件設計)和 磁盤空間問題。
- B-tree/B±tree 引擎的 內存組件設計 是為了提升讀性能,尤其是對 range Scan 較為友好。但是因為 B-tree 本身模型 in-place update 對寫并不友好。而且磁盤利用率并不高(內存page假如16k,寫2k 就得分配一個16k 的磁盤block)
- Hash 引擎的內存組件 因為是hash結構,除了scan 性能之外,內存消耗上是一個大問題。
總之,受限于數據結構的選擇,存儲引擎也分化出了自己的應用場景,而且需要圍繞各自索引的劣勢只能從軟件層來嘗試做非常多的設計和探索。受限于 物理服務器的CPU 計算資源 / 內存大小 / IO 性能的影響,軟件層的設計只能說是小心翼翼 😐 。
1.2 壓縮功能 導致的CPU瓶頸
壓縮功能在大集群規模下是必須要有的,顯著解決存儲成本 以及 磁盤壽命。問題也很明顯,CPU 會先成為瓶頸。
1.3 Crash-safe 崩潰異常的無奈選擇
因為有一部分數據在內存中,那為了保證存儲的可靠性 ,異常恢復是必須要的功能。
這樣 WAL / Double-write 就不可避免了,同一份數據的兩份存儲 造成的 寫放大 、空間放大 和 CPU的調度消耗 也是當前引擎設計的無奈之舉,且不依賴新硬件的情況下(PMEM)無法解決。
1.4 當前主流 加速硬件 較難滿足存儲性能提升的要求
前面提到過 主流加速硬件 FPGA / GPU 專為計算方向的性能提升做的,都能提供極致的的并行計算能力,但是并不一定適用于 數據庫存儲場景。
- 數據庫存儲 是計算+IO 一體的, 即使 X-Engine 探索了 FPGA off-load compaction 的方案,嘗試釋放 compaction 需要的算力到 FPGA 上,但是 IO 問題解決不了,走內核協議棧該有的讀寫放大一分不少,且整體的TCO 收益很難說(畢竟 compaction 的調度是在 update-heavy 場景,且 FPGA的成本可一點不低)。
- 主流加速硬件的接入復雜度,FPGA 的使用有自己的編程語言,畢竟內部的 host-memory 和 CU 的調度都是沒有 像傳統 服務器 os 的,內部的內存管理和計算資源的調度都得自己寫代碼(還是專有語言),不論是前期的設計 還是中期的開發 以及 后期的調試 復雜度還是非常高的(需要懂引擎 且 有相關領域的資深經驗 才能保證性能 以及 最重要的穩定性問題)。
這個痛點對與大多數的做數據庫內核的同學來說要求著實有點高。
2 XDP 設計原則
XDP 看到了這一些問題 ,希望能從一個 計算 + IO 的 軟硬結合的 全局設計來解決上面的問題。
主要的兩個展望是:
- Using Compute to Solve Non-Compute Problems. 希望能通過較多的計算能力解決一些之前引擎受限于算力的問題。
- A Unified Box,希望能提供一套即插即用的硬件解決方案,而不需要用戶過多的參與到硬件本身的編程細節上。
XDP 主要的探索方向在如下幾個方面:
2.1 數據結構上的優化
XDP 這里軟件層 實現了 index + log 的架構,內存中是 Partial sorted Hash 索引,并且寫入是 Append-only 方式 來保證維持磁盤的壽命和寫性能。
存在的問題也很明顯,索引對內存的占用問題。傳統機器受限于 CPU 資源問題,對于索引壓縮總是畏首畏尾。
XDP 大手一揮,不用擔心計算問題,只要內存占有能降下來,隨便設計,就有了下面的方案:
- 用戶 key 的 會生成一個定長的hash值(16B),每一個hash-bucket 用 Trie 存儲不同 Hash 值之間的差異bit。 論文中展開的細節是 DHT(Delta hash table)
- 內存中的數據會在flush到磁盤之前進行排序,保證對磁盤的寫入是順序寫
- 密集hash 索引(dense hash map) 用來解決沖突。
以上三種都是 CPU密集型的實現,需要大量得消耗計算資源。但是XDP 有自己的計算卡,不用擔心,只要 內存問題解決了就是好事。
2.2 解決 壓縮引入的CPU消耗
壓縮這個方向不言而喻,直接挑壓縮比最高的算法,有的是計算資源。
所以 XDP 選擇了 ZSTD 算法,保證了數據的最高壓縮比,降低磁盤存儲成本 而不用擔心 IO 問題。
2.3 異常恢復的設計
XDP 可以自己管理 ssd,所以提供了可選的 RAID 方案設計,這樣不用擔心 ssd 硬件異常導致的服務可用性問題。
更主要的是 XDP 提供了 capacitor-backed 備用電容器,用戶的更新數據放在 XDP內部的 SRAM上 不用擔心機器宕機之后的數據丟失問題,電容器提供的電量能保證 SRAM的 用戶數據持久化到磁盤。
這也就意味著,我們的存儲 crash-safe 設計 不需要考慮 WAL/ Double write這樣的問題 來降低引擎性能了,只需要有數據 塞到XDP就好了。
2.4 易于集成
XDP 甚至考慮到了用戶接口問題,提供了廣泛使用的 K/V 接口 以及 Block Interface(可以格式化文件系統 以及 分布式存儲 類似 ceph 這樣的應用 直接管理磁盤) 接口。
XDP的 集成不需要消耗系統服務器的計算資源,而且能夠提供可選的磁盤使用方案:用戶自己通過 os 管理磁盤,另一種通過 XDP 訪問磁盤(磁盤內部塊設備的調度XDP 自行管理)。
3 XDP 基本架構
XDP 硬件插在 PCIe 插槽上:
接下來看看 XDP 的基本組件,當然里面提到的組件并不是很全,真正使用起來的時候整個服務器也不是嚴格按照這個來分層,主要是展示 XDP 內用擁有的基礎組件,和 server 本有的 memory /cpu 是有差異的。
暴露了兩種 用戶可通過 XDP 訪問的接口,block interface 和 k/v 接口,對大多數場景來說都足夠使用了。
而且 其內部有自己的 Memory組件,并且提供了 capacitor-backed,不用擔心 有像 DRAM 掉電丟失的問題。
接下來主要看看 XDP 的 HW. indexing 內部調度 I/O 過程的基本架構如下:
- Arrival Buffer 接受最新的寫入 和 讀取。其內部還有更細粒度的buffer,分別放在 SRAM(xdp 的內存) 和 DRAM上,不過最新的寫入都會先放在 SRAM中。達到了一定閾值之后會將 Arrival Buffer中的數據 flush到 block clusters。
- Block clusters XDP 管理 ssd 的組件,將 磁盤塊映射為一個個 邏輯 block cluster。通過內存 index 能夠找到實際的user key 存放的 block cluster 以及 value 對應的偏移。
- Index,主要的 log+index 架構 中的 hash 索引存放的位置,實現上是一個 DHT(Delta hash table),內存占用極少。
- GC info,為了保證寫性能 以及 flash 磁盤壽命,提供了順序寫入。也就是需要通過 GC來進行過期/刪除 數據的清理。GC info 保存了一些GC調度的元數據。GC的過程 就和 LSM-tree compaction 過程一樣,從磁盤讀數據,排序,寫入新數據到磁盤,多了一個回插index的過程。
- GC buffers,將GC 后新的 k/v 數據先緩存到 DRAM中,回插到index 中 標識當前GC Task完成之后再清理。
知道這幾個組件大概的用途,其實對其軟件架構的設計就很清楚了(索引為 hash 形態的 log-structure Merged 結構)。
寫入的路徑很簡單:
上圖中的 1 --> 2 --> 3
讀路徑也很簡單:
A --> B --> C
GC 的過程:
5 --> 6 —> 7 —>8
因為它現在將這個軟件形態集成到了他們的內部 k/v Library中,且 Flush 和 GC都會排序(因為不缺,又不占有CPU的,又能提升寫性能,減少寫放大),他們眼光長遠得集成了 ZNS(zone namespace ssd),因為 ZNS 對順序寫非常友好,像Zenfs 的應用就是很好得將 rocksdb 的 compaction 和 SSD 內部的 GC機制結合起來,極大得減少了SSD 內部 FTL 引入的寫放大,提升Flash壽命。
關于ZNS的介紹,可以參考:ZNS: 解決傳統SSD問題的高性能存儲棧設計(fs–>io–>device)。
關于 index 內部的 DHT 設計提一下,利用不缺算力的優勢如何優化索引對內存的消耗:
index 存放的是 hkey,其形態如下:
對輸入的 user_key 通過murmur hash 生成一個 128bits 16B 的hash值,取前i 個bits 作為bucket id,j bits 作為 lslot id,剩下的作為指紋標識。
lslots 的 bits 假如是 11,則表示是第三個slot,lslot 和 bucket其實就是做了一個二級hash,也就是密集索引,消耗cpu,但足夠均勻。 每一個slot 有一個int 成員和pointer,標識映射到當前slot 的user_key有多少個 以及 lslots耗盡之后通過鏈表擴展一個bucket內部的slots個數。
如下案例:
假如 i, j都是2,則對于輸入的hash值前四個bits 且 1011 ,則表示當前 user_key被映射到了10 即 第3個bucket 的 11 第四個slot,里面有1個 use_key。
繼續向下看,剩下的 128 -i -j bits 用來作為具體user_key 的指紋數值。
存儲的時候僅僅會保存增量指紋之間的差異,核心目標是最少內存占用的情況下 保證讀時的唯一性。
比如對于 e1–e5 這 5個 user_key 的指紋數值,取的是前6個bits。當然,這里是因為6個bits 已經能夠兩兩區分他們之間的差異了,實際可能需要更多的bits,也就需要拿更多的bits進行 Trie的構造了。
將 entry 之間的差異 逐個插入 Trie 樹中:
比如 e1 和 e2 之間的差異是到 下標為2 的位置 010 和 011 有差異,則會在 e1,e2的公共索引節點標識其差異下標所在位置 idx 2。
同理,e1 和 e3 再 idx 0 位置就有差異,構造的過程就將 e3 放在右子樹中。右子樹中的 idx 5是 對比 e3,e5時 發現在 下標為 5的位置才有差異 添加進來的。
這樣整個 Delta Trie 就構造好了,這個過程對于所有屬于當前 slot的 entry都要先收集最大的差異bits,再構造Trie,整個過程會有極多的計算資源的消耗,但都被財大氣粗的 計算硬件包攬。優勢就是 極大得節省了存儲空間。
不過Trie 的Scan 性能可能并不會友好,但是不需要 server 的 CPU參與,這就是最大的優勢了。
4 總結
總的來說 XDP 計算硬件 結合了 IO 鏈路所展示基本解決方案 讓我們看到了存儲和新硬件結合的曙光。當然,其方案內部的設計 復雜度是非常高的(尤其是對磁盤的管理 – os 是 generic block layer --> io sheduler --> block layer,它現在要自己管理)。
總結
以上是生活随笔為你收集整理的Pliops XDP(Extreme Data Processor)数据库存储设计的新型加速硬件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吉他要多少钱啊?
- 下一篇: 拙字开头的成语有哪些?