看圖瞭解RocksDB 頂 原 薦

它是一個高性能的Key-Value數據庫。設計了完善的持久化機制,同時保證性能和安全性。能夠良好的支持範圍查詢,因爲K-V記錄就是按照Key來排序的。

 

下圖爲寫入的流程:

b06ff0742ae3821223fb29274aef0b3e653c2f67

可以看到主要的三個組成部分,內存結構memtable,類似事務日誌角色的WAL文件,持久化的SST文件。

數據會放到內存結構memtable,一定條件下觸發寫到到SST文件。寫入WAL文件是可選的,用來恢復未寫入到磁盤的memtable。

 

下圖展示了讀取的層次:

be279f90e727321873d47cbbdc97706d46ee9f37

 

memtable和SST文件組成數據的全集。之上是緩存層,緩存爲提升查詢性能做了分片,底層都採用hash查詢,不同緩存結構的區別在於熱點數據的替換邏輯。訪問數據庫時,都是訪問的打開時間點的view(我猜測一個key有不同時間戳的多條記錄)。除了直接查詢db,還提供了查詢快照的機制。直接訪問db時,會持有文件句柄,這樣多個SST文件合併時,已經被合併但被訪問的文件就不能被刪除。而快照機制保證了訪問過程中文件能被刪除(我並未想明白如何做到的),不過打開期間被刪除的key的記錄還會在新合併的文件裏存在。

 

memtable的結構有幾種可選,本質都是排序的結構(爲了支持範圍查詢)

9ec7aa51eae012d152f677869b6b2746486b8fab

其中之一是上圖的跳躍表,不瞭解跳躍表機制的讀者可以簡單理解爲有序支持近似二分查找的時間複雜度爲log2(N)的結構

f4e36ab8af1e045174ff6875f4992e32a532ec79

另外一種是hash結合跳躍表,是按照key的前綴做hash,單獨訪問一個key時性能更好,範圍查詢性能會差些

 

WAL文件結構如下圖,按照寫入的順序來存儲變長的K-V,按照固定長度來分組存儲(可能一個K-V跨多個分組)的目的是便於讀取

770db51ff074cfede56f2dd0dd65d7380b5d632e

 

支持幾種SST文件結構

08b51387b3ac49e9d4973cc416c94deb0aad52f1

上圖爲按照多塊來存儲的結構。每塊的K-V都是有序的,而多塊也是有序的。文件中包含元數據相關的信息,包括數據壓縮字典、過濾器等。會按照數據塊所屬的K-V範圍來創建索引,爲提升查詢性能會給索引分片。

56765ff825d19c49ee00045b25e890ac93aeedc5

另外一種結構是每個K-V來存儲。它的索引比較特殊,由hash結構和二進制查找緩存兩部分組成。依然按照key的前綴做hash,如果桶對應的K-V記錄很少,則直接指向第一個key(有多個key屬於該桶)的記錄位置。如果屬於桶的K-V記錄多於16條,或者包含多於一個前綴的記錄,則先指向二進制查找緩存(先二分查找),而後指向第一個key的記錄位置。

 

隨着K-V的寫入,會生成很多的SST文件,這部分文件需要被合併到一起。從而降低打開文件數量,並且移除已經不存在的記錄。通常可以配置兩種方式,通用合併(下圖左側)與level合併(右側)。

c60d54d533ec0205bc7d9094cd02f1a3acfe2f79

其中一個概念是level,可以簡單理解成越老的數據在越高的level(也就是數據最初寫入到最低的level,level0就是memtable)。

我將通用合併簡單理解爲一種簡單粗暴的合併,可以儘量降低寫磁盤的壓力,會增大讀取的壓力,臨時空間佔用大。

一般多采用level合併的方式。每個level都有max大小,超出後會觸發本level與下一level的文件合併到一起。不同level的合併是可以併發執行的。

 

對rocksdb做個總結。所有記錄在業務上是有序的,對key的查詢其實會執行類似二分查找。持久化是通過寫入有序文件來實現的。高性能的寫入是通過先寫入內存結構來保證的(寫滿的內存結構刷到持久化文件)。提供了level機制對數據做分層,優先查詢最新寫入的level來優化查詢性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章