五、.ldb文件
關於ldb文件說明:
1)ldb文件是按照block存儲,一個block默認大小爲4KB,當內存數據增長到4KB則進行寫文件操作。
2)從leveldb v1.14版本開始,數據存儲到了後綴名爲ldb文件中,不在存儲到sst文件中。
3)一個ldb文件包含:data block,filter block,meta index block,data index block以及footer。其中filter block是可選的。
存儲格式整體如下:
5.1 Block-Entry格式
所有的Block格式都是相同的,一個Block默認大小爲4KB,當Block所佔內存空間大於4KB則flush到文件中。一個Block可以包含多個entry,每個entry只包含三個元素:
字段名 | 說明 | 備註 |
Block Contents | block存儲的內容,內容格式由上層決定。這裏可以參考下面章節 |
不定長,具體長度保存在 data index block中 |
Compression Type |
爲了減少磁盤空間,可對數據進行壓縮,取值爲:kNoCompression、kSnappyCompression | 1字節 |
CRC |
crc數據校驗和 | 4字節 |
5.2 Data Block
5.2.1 重啓點
leveldb爲了提升性能,抽象出一個重啓點概念,感覺挺玄乎其實就是偏移量.一個Block至少有一個重啓點.那麼重啓點等於什麼呢? 等於16個Block-Entry大小.舉例說明:
例子1: 一個block存儲了19條Block-Entry,每條Block-entry是64字節,那麼重啓點一共有兩個分別爲0,16*64
例子2: 一個block存儲了34條Block-Entry,每條Block-entry是64字節,那麼重啓點一共有三個分別爲0,16*64,32*64
例子3: 一個block存儲了1條Block-Entry,這條Block-Etnry是5KB字節,那麼重啓點只有一個是0
說明:
1) 一個Block至少有一個重啓點,其重啓點值爲0
2) 一個Block默認大小是4KB,如果所有Block-Entry所佔內存字節大於4KB則將這個Block刷新到文件中,所以會出現例子3的場景
5.2.2 Block Contents格式
上面介紹了重啓點,下面介紹在Data Block類型下Block Contents格式如下所示:
字段說明:
序號 | 字段 | 說明 | 備註 |
1 | key值相同部分大小 | 本條記錄相對於上一條記錄的key,有多少字符是相同的。 | Varint32類型 |
2 | key值不同部分大小 | 本條記錄相對於上一條記錄的key,有多少字符是不同的。 | Varint32類型 |
3 | value大小 | 本條記錄value內容大小。 | Varint32類型 |
4 | key值不同的部分 實際內容 | key值不同內容 | 字節數組 |
5 | value內容 | 本條記錄value實際內容 | 至此1-5構成一條Record |
6 | 重啓點值以及重啓點個數 |
舉例說明,分別插入如下記錄:
記錄 | key值相同部分大小 | key值不同部分大小 | value大小 | key不同內容 | value內容 |
helloworld:my-helloworld | 0 | 10 | 13 | helloworld | my-helloworld |
helloleveldb:my-helloleveldb | 5 | 7 | 15 | leveldb | my-helloleveldb |
myhello:good | 0 | 7 | 4 | myhello | good |
helloworld2:my-helloworld2 | 0 | 11 | 14 | helloworld2 | my-helloworld2 |
5.3 、Filter Block
該部分是可選的,如果在創建db的時候指定的Options中設置了filter_policy,我們可以自定義用戶過濾策略,目前leveldb提供的過濾策略爲Bloom Filter。 當指定了filter_policy那麼在生成ldb文件時就會存儲Filter Block相關信息。
5.4、Meta Index Block
該部分是主要用於後續leveldb擴展使用,目前元信息比較少,主要用於保存filter policy名字。
5.5、Data Index Block
index block存儲格式與data block存儲格式是一樣的,可參考data block格式,此處不再放圖展示.一個ldb文件中存在多個Data Block,每個Data Block在ldb中位置以及DataBlock實際大小都保存在Data Index Block中。
1)Data Index Block有且只有一個。
2)Data Index Block中每一個Entry對應一個Data Block元信息,元信息包含:Data Block最大InternalKey,Data Block在ldb文件中偏移量以及DataBlock實際大小。所以可以將Data Index Block理解爲Data Block元信息管理者。
5.6、Footer
Footer的大小始終是48字節,最後8字節是魔鬼數字,保證文件有效性,存儲結構在已經給出,具體字段參數含義如下:
字段 | 含義 |
meta index offset | meta index block在ldb文件中偏移量,類型爲varint64 |
meta index size | meta index block大小,類型爲varint64 |
data index offset | data index block在ldb文件中偏移量,類型爲varint64 |
data index size |
data index block大小,類型爲varint64 |
padding | 索引相關一共佔用40字節,padding是爲了補齊 |
MagicNumber | 8字節,魔鬼數字 |
leveldb在讀取ldb文件時會從文件尾部偏移48字節,用於讀取ldb文件元數據,並對各個字段進行解析。
六、總結
花兩個篇博客來闡明leveldb存儲結構,希望能夠幫助大家縷清思路。後面開始介紹源碼相關內容。