利用leveldb實現文件系統的目錄樹

利用leveldb實現文件系統的目錄樹

目錄樹維護了整個文件系統的元信息,全部對文件系統中文件的增刪查改操做都首先須要通過目錄樹的操做才能進行。百度開源的分佈式文件系統BFS(開源地址:https://github.com/baidu/bfs)利用leveldb,實現了目錄樹的管理,使得目錄樹的實現很是簡潔,同時對目錄樹的操做十分高效。本文將爲你解析其具體設計及實現思路。git

目錄樹爲一個樹型結構,而leveldb是一個kv存儲引擎,所以,若是想用經過leveldb實現目錄樹,則須要把樹型結構映射成kv的扁平化結構。github

單獨就每一個文件或者目錄來說,其信息只須要一條kv記錄便可保存,而這條kv中的value須要保存該目錄或文件的屬性信息,可變更的空間不大。因此,從樹型結構到kv記錄的映射 ,關鍵在於key的選取。緩存

在BFS的目錄樹中,定義了一個int64_t的整型數字做爲EntryID,每一個文件或目錄擁有一個EntryID,而且全局惟一,根目錄的EntryID規定爲1。假設有以下目錄結構:微信

/home/dirx/
          /filex
      diry/
          /filey
/tmp/
     filez

按照建立順序,咱們依次給/home分配的EntryID爲2,/tmpEntryID爲3,/home/dirxEntryId爲4,/home/diryEntryID爲5,/home/tmp/filezEntryID爲6,/home/dirx/filexEntryID爲7,/home/diry/fileyEntryID爲8。架構

注意到每一個目錄擁有一個本身的EntryID的同時,又確定擁有一個父目錄,其父目錄又確定擁有一個EntryID,能夠利用這一點,經過父目錄的EntryID和子目錄中的文件名,來肯定一條記錄的key:對於每一個文件或者目錄,咱們規定:每條kv記錄的key爲 "父目錄的EntryID+自身文件名",同時在value中存儲本身的EntryID這樣編碼後,上述目錄樹即可以表示爲以下kv記錄:分佈式

1home -> 2 + xxx
1tmp -> 3 + xxx
2dirx -> 4 + xxx
2diry -> 5 + xxx
3filez -> 6 + xxx
4filex -> 7 + xxx
5filey -> 8 + xxx

其中,xxx表示該目錄或文件的其它信息,如大小,建立時間,實際數據存放位置等。編碼

到此,目錄樹這個樹型結構,便已經平展成爲一條條的kv記錄,對目錄樹的操做,便轉化成了對某幾條kv記錄的操做:設計

  • 對於建立文件操做,好比想建立/home/work/目錄,則首先在/目錄中查找home目錄,因爲/EntryID爲1,因此第一次查找時,key爲1home,而後讀出其value,解析後發現/homeEntryID爲2,則將此EntryID記下,繼續往下走,發現work即爲所須要建立的文件,則爲其申請一個EntryID(假設爲9),此時,寫入一條記錄,按照上面的規則,其key爲2work,value爲work建立的時間等信息,以及workEntryID(9)
  • 對於刪除操做,好比把剛剛建立的/home/work目錄刪除,只須要將key爲2work的這條記錄刪除便可
  • 對於讀取操做,好比想讀取/home/dirx/filex文件中的內容,則首先讀取1home這條key所對應的value,解析發現value中記錄的EntryID爲2,而後再去讀取2dirx這條key所對應的value,解析發現value中記錄的EntryID爲4,而後再去讀取4filex這條key所對應的value,從裏面解析出/home/dirx/filex的實際數據存放位置,進行文件內容的讀取
  • 對於List目錄操做,好比想看看根目錄下有哪些文件和目錄,因爲每一個文件和目錄在存儲時,其key中都包含父目錄的EntryID,所以,只需進行一次掃描便可。好比ls /,則只需掃描leveldb中,以1\0x0爲前綴的key便可,當遇到2時中止,所得結果即爲/目錄下的全部內容
  • 對於Rename操做,只須要改動其key便可。好比想要把/home/diry/filey文件移動到home/dirx目錄中,按照以前的規則,/home/diry/filey在leveldb中存儲的key爲5filey/home/dirxEntryID爲4,把5filey這條記錄中的內存讀取出來,以4filey爲key,再次存儲到leveldbk ,而後將5filey這條記錄刪除,即完成了Rename操做

這樣,一個目錄樹所須要的基本操做便已經支持,因爲leveldb引擎自己寫入速度較快,而且在讀取時,內部自己已經有cache來緩存住較熱的kv數據,而且緩存大小可配置,因此一個很是簡潔高效的目錄樹便實現了~code

想要了解BFS實現中的其它細節 ,請關注https://github.com/baidu/bfs,或者關注微信公衆號『百度網頁搜索基礎架構團隊』獲取更多技術信息內存

相關文章
相關標籤/搜索