leveldb插入資料時,首先將資料插入memtable,當memtable資料量達到一定大小時,當前memtable賦值給immemtable(也是memtable型別,但是這個是唯讀的),然後產生乙個新的memtable用於後續的資料插入,immemtable將會把資料持久化到磁碟中。
磁碟檔案是按分level的,immemtable首先將資料compaction到level0檔案中,稱為minor compaction。所以level0之間可能存在資料重疊。當某個level i檔案達到一定數量時,選擇乙個檔案與level i+1合併,稱為major compaction。可以再看下leveldb模型圖:
leveldb將sst檔案切割成乙個乙個塊,每個塊都是有資料+型別+crc碼,所以每個sst檔案開啟格式都是如下圖所示:
leveldb根據用途將這些block又分為資料塊,元資料塊,元資料塊索引塊,資料塊索引塊和檔案尾。
資料塊主要就是儲存資料的地方,immemtable中的鍵值對就是儲存在資料塊;
元資料塊主要就是用於過濾,加快檢索速度。
元資料塊索引塊,leveldb預設乙個過濾器,所以元資料塊索引塊就一條記錄;
資料塊索引塊,儲存每乙個資料塊的偏移和大小,用於定位索引塊。
檔案尾,儲存了資料塊索引塊和元資料塊索引塊,用於讀取這兩個塊; 模型圖如下:
例如要讀取某個data block,可以先讀取出footer,然後讀取出index block,由於index block中儲存各個資料塊的偏移和大小,就可以讀取出這個data block。
接下來,將分別介紹各種塊的格式。
首先介紹的是資料塊的格式,模型圖如下:
資料塊上部分主要儲存的是一條條的記錄,記錄的格式如下:
每一條記錄有key共享長度+key非共享長度+value長度+key非共享內容+value內容組成。leveldb為了節約儲存,並不是儲存每一條記錄鍵值的完整值,而是兩條記錄如果有共享的部分,那麼第二條記錄可以和第一條共享共享的部分。例如第一條記錄為hello world:11,第二條記錄為hello you:9,那麼第一條記錄儲存格式為:0+11+2+hello world+11,首先說明下,第一條記錄共享長度為0,因為它沒有上條記錄,所以就沒有共享。那麼第二條記錄儲存格式為:6+3+1+you+9。
資料塊restart[i]表示乙個共享記錄的開始,這條記錄和第一條記錄一樣,共享長度為0,restart[i]儲存就是這個共享記錄的偏移。
資料塊的最後乙個部分為restart點的個數,圖中為3個。
meta block儲存主要是過濾器的內容,先給出模型圖如下:
filter i儲存的是這個每個資料塊的鍵值,當要讀取i資料塊時,可以先到filter i查詢鍵值,如果沒有找到,就沒必要讀取這個塊了。因為filter比data塊小,讀取io消耗更小。filter i 偏移表示filter i在meta block的偏移量,偏移陣列的位置就是第乙個filter 1 偏移的位址,最後g(base)用於決定資料量多大時,建立乙個filter。
meta block格式相對簡單,因為leveldb預設只有乙個過濾器,當然使用者可以自己定義過濾器。格式如下:
其中,key="filter."+過濾器名字。後面兩個字段表示meta block塊的在檔案的偏移量和大小,方便讀取。
index block格式如下:
例如第i個data block最小鍵值為hello,最大鍵值為world;第i+1個data block最小鍵值為www,最大鍵值為yellow,所以第i個data block的鍵值欄位為world。
sst檔案最後一部分為footer,格式如下:
leveldb原始碼分析之Arena
arena 是 leveldb 專案裡面使用的輕量級的記憶體池物件,leveldb 用這個物件來管理記憶體的分配,簡化了 new 和 delete 的呼叫,我們也可以從這個輕量級的記憶體池物件學習 google 大神工程師是如何管理記憶體的。arena 記憶體管理模型 arena 使用下面幾個成員變...
leveldb原始碼分析之SSTable檔案例項講解
sstable檔案是memtable 資料到一定閾值寫入檔案形成的,由於記憶體容量總是有限的,將一定量資料寫入磁碟可以存放更多資料,所以leveldb相比redis能存放更多資料。既然資料持久化到磁碟,那麼還有必然涉及到從磁碟中查詢資料,從磁碟中查詢資料與從記憶體中查詢資料的效率是不一樣的,所以ss...
leveldb原始碼分析 之 入門使用
leveldb是google開源的乙個key value儲存引擎庫,類似於開源的lucene索引庫一樣。其他的軟體開發者可以利用該庫做二次開發,來滿足定製需求。leveldb採用日誌式的寫方式來提高寫效能,但是犧牲了部分讀效能。為了彌補犧牲了的讀效能,一些人提議使用ssd作為儲存介質。對於本地化的k...