1. 程式人生 > >leveldb原始碼分析之sst檔案格式

leveldb原始碼分析之sst檔案格式

轉載:http://luodw.cc/2015/10/21/leveldb-09/

之前leveldb分析,講解了leveldb兩大元件memtable和log檔案。這篇文章主要分析leveldb將記憶體資料寫入磁碟檔案,這些磁碟檔案的格式,下一篇文章再分析原始碼。

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檔案格式

leveldb將sst檔案切割成一個一個塊,每個塊都是有資料+型別+CRC碼,所以每個sst檔案開啟格式都是如下圖所示:sst檔案格式

leveldb根據用途將這些block又分為資料塊,元資料塊,元資料塊索引塊,資料塊索引塊和檔案尾。

  1. 資料塊主要就是儲存資料的地方,immemtable中的鍵值對就是儲存在資料塊;
  2. 元資料塊主要就是用於過濾,加快檢索速度。
  3. 元資料塊索引塊,leveldb預設一個過濾器,所以元資料塊索引塊就一條記錄;
  4. 資料塊索引塊,儲存每一個數據塊的偏移和大小,用於定位索引塊。
  5. 檔案尾,儲存了資料塊索引塊和元資料塊索引塊,用於讀取這兩個塊; 模型圖如下:

sst檔案具體格式

例如要讀取某個data block,可以先讀取出footer,然後讀取出index block,由於index block中儲存各個資料塊的偏移和大小,就可以讀取出這個data block。

接下來,將分別介紹各種塊的格式。

data block格式

首先介紹的是資料塊的格式,模型圖如下:

data block格式

資料塊上部分主要儲存的是一條條的記錄,記錄的格式如下:

sst記錄格式

每一條記錄有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格式

Meta block儲存主要是過濾器的內容,先給出模型圖如下:Meta block格式

Filter i儲存的是這個每個資料塊的鍵值,當要讀取i資料塊時,可以先到Filter i查詢鍵值,如果沒有找到,就沒必要讀取這個塊了。因為filter比data塊小,讀取IO消耗更小。Filter i 偏移表示Filter i在Meta block的偏移量,偏移陣列的位置就是第一個Filter 1 偏移的地址,最後g(base)用於決定資料量多大時,建立一個Filter。

索引塊的格式

Meta block格式

Meta block格式相對簡單,因為leveldb預設只有一個過濾器,當然使用者可以自己定義過濾器。格式如下:Meta block格式

其中,key="filter."+過濾器名字。後面兩個欄位表示Meta block塊的在檔案的偏移量和大小,方便讀取。

index block格式

index block格式如下:index block格式第一個欄位儲存第i塊最大的鍵值,但是必須比第i+1個data block最小鍵值小。因為block資料是有序的(skiplist資料為有序),所以有最大鍵值,就可以知道這個塊儲存的資料的鍵值範圍。第二個和第三個欄位分別表示第i個data block的偏移量和大小,方便讀取。

例如第i個data block最小鍵值為hello,最大鍵值為world;第i+1個data block最小鍵值為www,最大鍵值為yellow,所以第i個data block的鍵值欄位為world。

Footer格式

sst檔案最後一部分為Footer,格式如下:Footer格式前兩個儲存Metaindex塊的偏移量和大小以及Index塊的偏移量和大小。也是為了後續讀取方便。Padding填充部分,Magic number魔數,用於驗證正確性。

sst檔案格式大概就如上所示,下一篇文章,分下原始碼。