levelDB原始碼分析 SSTable

2021-06-07 03:38:30 字數 3060 閱讀 6146

sstable是bigtable中至關重要的一塊,對於leveldb來說也是如此,對leveldb的sstable實現細節的了解也有助於了解bigtable中一些實現細節。

本節內容主要講述sstable的靜態布局結構,sstable檔案形成了不同level的層級結構,至於這個層級結構是如何形成的我們放在後面compaction一節細說。本節主要介紹sstable某個檔案的物理布局和邏輯布局結構,這對了解leveldb的執行過程很有幫助。

leveldb不同層級都有乙個或多個sstable檔案(以後綴.sst為特徵),所有.sst檔案內部布局都是一樣的。上節介紹log檔案是物理分塊的,sstable也一樣會將檔案劃分為固定大小的物理儲存塊block,但是兩者邏輯布局大不相同,根本原因是:log檔案中的記錄是key無序的,即先後記錄的key大小沒有明確大小關係,而.sst檔案內部則是根據記錄的key由小到大排列的,從下面介紹的sstable布局可以體會到key有序是為何如此設計.sst檔案結構的關鍵。

圖1 .sst檔案的分塊結構

圖2 邏輯布局

從圖2可以看出,從大的方面,可以將.sst檔案劃分為資料儲存區和資料管理區,資料儲存區存放實際的key:value資料,資料管理區則提供一些索引指標等管理資料,目的是更快速便捷的查詢相應的記錄。兩個區域都是在上述的分塊基礎上的,就是說檔案的前面若干塊實際儲存kv資料,後面資料管理區儲存管理資料。管理資料又分為四種不同型別:紫色的meta block,紅色的metablock index和藍色的index block以及乙個檔案尾部塊footer。

leveldb 1.2版對於meta block尚無實際使用,只是保留了乙個介面,估計會在後續版本中加入內容,下面我們看看index block和檔案尾部footer的內部結構。

圖3 index block結構

圖3是index block的內部結構示意圖。再次強調一下,data block內的kv記錄是按照key由小到大排列的,index block的每條記錄是對某個data block建立的索引資訊,每條索引資訊包含三個內容:data block中key上限值(不一定是最大key)、data block在.sst檔案的偏移和大小,以圖3所示的資料塊i的索引index i來說:紅色部分的第乙個字段記載大於等於資料塊i中最大的key值的那個key,第二個字段指出資料塊i在.sst檔案中的起始位置,第三個字段指出data block i的大小(有時候是有資料壓縮的)。後面兩個欄位好理解,是用於定位資料塊在檔案中的位置的,第乙個字段需要詳細解釋一下,在索引裡儲存的這個key值未必一定是某條記錄的key,以圖3的例子來說,假設資料塊i 的最小key=「samecity」,最大key=「the best」;資料塊i+1的最小key=「the fox」,最大key=「zoo」,那麼對於資料塊i的索引index i來說,其第乙個字段記載大於等於資料塊i的最大key(「the best」),同時要小於資料塊i+1的最小key(「the fox」),所以例子中index i的第乙個欄位是:「the c」,這個是滿足要求的;而index i+1的第乙個欄位則是「zoo」,即資料塊i+1的最大key。

檔案末尾footer塊的內部結構見圖4,metaindex_handle指出了metaindex block的起始位置和大小;inex_handle指出了index block的起始位址和大小;這兩個字段可以理解為索引的索引,是為了正確讀出索引值而設立的,後面跟著乙個填充區和魔數(0xdb4775248b80fb57)。

圖4 footer

上面主要介紹的是資料管理區的內部結構,下面我們看看資料區的乙個block的資料部分內部是如何布局的,圖5是其內部布局示意圖。

圖5 data block內部結構

從圖中可以看出,其內部也分為兩個部分,前面是乙個個kv記錄,其順序是根據key值由小到大排列的,在block尾部則是一些「重啟點」(restart point),其實是一些指標,指出block內容中的一些記錄位置。

「重啟點」是幹什麼的呢?簡單來說就是進行資料壓縮,減少儲存空間。我們一再強調,block內容裡的kv記錄是按照key大小有序的,這樣的話,相鄰的兩條記錄很可能key部分存在重疊,比如key i=「the car」,key i+1=「the color」,那麼兩者存在重疊部分「the c」,為了減少key的儲存量,key i+1可以只儲存和上一條key不同的部分「olor」,兩者的共同部分從key i中可以獲得。記錄的key在block內容部分就是這麼儲存的,主要目的是減少儲存開銷。「重啟點」的意思是:在這條記錄開始,不再採取只記載不同的key部分,而是重新記錄所有的key值,假設key i+1是乙個重啟點,那麼key裡面會完整儲存「the color」,而不是採用簡略的「olor」方式。但是如果記錄條數比較多,隨機訪問一條記錄,需要從頭開始一直解析才行,這樣也產生很大的開銷,所以設定了多個重啟點,block尾部就是指出哪些記錄是這些重啟點的。

圖6 記錄格式

在block內容區,每個kv記錄的內部結構是怎樣的?圖6給出了其詳細結構,每個記錄包含5個字段:key共享長度,key非共享長度,value長度,key非共享內容,value內容。比如上面的「the car」和「the color」記錄,key共享長度5;key非共享長度是4;而key非共享內容則實際儲存「olor」;value長度及內容分別指出key:value中value的長度和儲存實際的value值。

上面講的這些就是.sst檔案的全部內部奧秘。

block格式及相關操作請參閱《leveldb原始碼分析-sstable:block》。

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

leveldb插入資料時,首先將資料插入memtable,當memtable資料量達到一定大小時,當前memtable賦值給immemtable 也是memtable型別,但是這個是唯讀的 然後產生乙個新的memtable用於後續的資料插入,immemtable將會把資料持久化到磁碟中。磁碟檔案是按...

leveldb原始碼分析1

leveldb是乙個key value型的儲存引擎,由google開發,並宣布在bsd許可下開放源 plain git clone plain cd leveldb make all 此時生成libleveldb.a庫檔案。拷貝leveldb的標頭檔案到 usr include下 plain cp ...

Leveldb原始碼分析 1

前言 看了一點oceanbase,沒有意志力繼續堅持下去了,暫時就此中斷,基本上算把master看完了,比較重要的update server和merge server 卻沒有細看。中間又陸續研究了hadoop的原始碼,主要是name node和寫入pipeline。主要的目的是想看看name nod...