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

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