?
LevelDb本質上是一套存儲系統以及在這套存儲系統上提供的一些操作接口。為了便于理解整個系統及其處理流程,我們可以從兩個不同的角度來看待LevleDb:靜態角度和動態角度。從靜態角度,可以假想整個系統正在運行過程中(不斷插入刪除讀取數據),此時我們給LevelDb照相,從照片可以看到之前系統的數據在內存和磁盤中是如何分布的,處于什么狀態等;從動態的角度,主要是了解系統是如何寫入一條記錄,讀出一條記錄,刪除一條記錄的,同時也包括除了這些接口操作外的內部操作比如compaction,系統運行時崩潰后如何恢復系統等等方面。
本節所講的整體架構主要從靜態角度來描述,之后接下來的幾節內容會詳述靜態結構涉及到的文件或者內存數據結構,LevelDb日知錄后半部分主要介紹動態視角下的LevelDb,就是說整個系統是怎么運轉起來的。
LevelDb作為存儲系統,數據記錄的存儲介質包括內存以及磁盤文件,如果像上面說的,當LevelDb運行了一段時間,此時我們給LevelDb進行透視拍照,那么您會看到如下一番景象:
圖1.1:LevelDb結構
從圖中可以看出,構成LevelDb靜態結構的包括六個主要部分:內存中的MemTable和Immutable MemTable以及磁盤上的幾種主要文件:Current文件,Manifest文件,log文件以及SSTable(Sorted String table)文件。當然,LevelDb除了這六個主要部分還有一些輔助的文件,但是以上六個文件和數據結構是LevelDb的主體構成元素。
LevelDb的Log文件和Memtable與Bigtable論文中介紹的是一致的,當應用寫入一條Key:Value記錄的時候,LevelDb會先往log文件里寫入,成功后將記錄插進Memtable中,這樣基本就算完成了寫入操作,因為一次寫入操作只涉及一次磁盤順序寫和一次內存寫入,所以這是為何說LevelDb寫入速度極快的主要原因。
Log文件在系統中的作用主要是用于系統崩潰恢復而不丟失數據,假如沒有Log文件,因為寫入的記錄剛開始是保存在內存中的,此時如果系統崩潰,內存中的數據還沒有來得及Dump到磁盤,所以會丟失數據(Redis就存在這個問題)。為了避免這種情況,LevelDb在寫入內存前先將操作記錄到Log文件中,然后再記入內存中,這樣即使系統崩潰,也可以從Log文件中恢復內存中的Memtable,不會造成數據的丟失。
當Memtable插入的數據占用內存到了一個界限后,需要將內存的記錄導出到外存文件中,LevleDb會生成新的Log文件和Memtable,原先的Memtable就成為Immutable Memtable,顧名思義,就是說這個Memtable的內容是不可更改的,只能讀不能寫入或者刪除。新到來的數據被記入新的Log文件和Memtable,LevelDb后臺調度會將Immutable Memtable的數據導出到磁盤,形成一個新的SSTable文件。SSTable就是由內存中的數據不斷導出并進行Compaction操作后形成的,而且SSTable的所有文件是一種層級結構,第一層為Level 0,第二層為Level 1,依次類推,層級逐漸增高,這也是為何稱之為LevelDb的原因。
SSTable中的文件是Key有序的,就是說在文件中小key記錄排在大Key記錄之前,各個Level的SSTable都是如此,但是這里需要注意的一點是:Level 0的SSTable文件(后綴為.sst)和其它Level的文件相比有特殊性:這個層級內的.sst文件,兩個文件可能存在key重疊,比如有兩個level 0的sst文件,文件A和文件B,文件A的key范圍是:{bar, car},文件B的Key范圍是{blue,samecity},那么很可能兩個文件都存在key=”blood”的記錄。對于其它Level的SSTable文件來說,則不會出現同一層級內.sst文件的key重疊現象,就是說Level L中任意兩個.sst文件,那么可以保證它們的key值是不會重疊的。這點需要特別注意,后面您會看到很多操作的差異都是由于這個原因造成的。
SSTable中的某個文件屬于特定層級,而且其存儲的記錄是key有序的,那么必然有文件中的最小key和最大key,這是非常重要的信息,LevelDb應該記下這些信息。Manifest就是干這個的,它記載了SSTable各個文件的管理信息,比如屬于哪個Level,文件名稱叫啥,最小key和最大key各自是多少。下圖是Manifest所存儲內容的示意:
圖2.1:Manifest存儲示意圖
圖中只顯示了兩個文件(manifest會記載所有SSTable文件的這些信息),即Level 0的Test1.sst和Tes2t.sst文件,同時記載了這些文件各自對應的key范圍,比如Test1.sst的key范圍是“abc”到“hello”,而文件Test2.sst的key范圍是“bbc”到“world”,可以看出兩者的key范圍是有重疊的。
Current文件是干什么的呢?這個文件的內容只有一個信息,就是記載當前的manifest文件名。因為在LevleDb的運行過程中,隨著Compaction的進行,SSTable文件會發生變化,會有新的文件產生,老的文件被廢棄,Manifest也會跟著反映這種變化,此時往往會新生成Manifest文件來記載這種變化,而Current則用來指出哪個Manifest文件才是我們關心的那個Manifest文件。
以上介紹的內容就構成了LevelDb的整體靜態結構,在接下來的內容中,我們會首先介紹重要文件或者內存數據的具體數據布局與結構。
下一節介紹LOG文件
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
