Bitcask 存儲模型


Bitcask 存儲模型

 

Bitcask 是一個日志型、基於hash表結構的key-value存儲模型,以Bitcask為存儲模型的K-V系統有 Riak beansdb 新版本。

 

日志型數據存儲

何謂日志型?就是append only,所有寫操作只追加而不修改老的數據,就像我們的各種服務器日志一樣。在Bitcask模型中,數據文件以日志型只增不減的寫入文件,而文件有一定的大小限制,當文件大小增加到相應的限制時,就會產生一個新的文件,老的文件將只讀不寫。在任意時間點,只有一個文件是可寫的,在Bitcask模型中稱其為active data file,而其他的已經達到限制大小的文件,稱為older data file,如下圖:

 

文件中的數據結構非常簡單,是一條一條的數據寫入操作,每一條數據的結構如下:

 

 

上面數據項分別為key,value,key的大小,value的大小,時間戳(應該是),以及對前面幾項做的crc校驗值。(數據刪除操作也不會刪除舊的條目,而是將value設定為一個特殊的值以作標示)
數據文件中就是連續一條條上面格式的數據,如下圖:

 

 

上面就是日志型的數據文件,但文件這樣持續的存下去,肯定是會無限膨脹的,為了解決個問題,和其他日志型存儲系統一樣Bitcask也有一個定期的merge操作。
merge操作,即定期將所有older data file中的數據掃描一遍並生成新的data file(沒有包括active data file 是因為它還在不停寫入),這里的merge其實就是將對同一個key的多個操作以只保留最新一個的原則進行刪除。每次merge后,新生成的數據文件就不再有冗余數據了。

 

 

事實上,Bitcask 中有兩類文件:

  • xxx.w:即上面說的數據文件,xxx 是一個數值,寫滿1G后將新建文件,數值自增,程序往數值最大的一個文件 Append 數據;
  • write.pos:記錄當前數值最大的 xxx.w 文件(FileNo),以及該文件的寫位移(Offset),方便在寫數據的時候快速定位;

 

定義了數據文件和記錄寫位移的文件后,我們通過以下方式實現數據寫:

  • 檢查當前 xxx.w 文件寫位移 + 當前要寫入的數據長度是否大於MAX_FILE_SIZE(即一個數據文件的最大size,這里我們定義為1G);如果大於則創建一個序號增 1 的 .w 文件;
  • 調用 open、write 函數將數據追加到當前 .w 文件結尾;
  • 更新 write.pos 中 FileNo、Offset 的值;

 

 

 

基於hash表的索引數據

寫操作有 write.pos 文件指明要寫入的 FileNo 和 Offset;但對於讀操作,如何快速地從浩瀚的數據中,找到某個 key 對應數據所在的文件和文件位移呢?這要依賴於內存中的hash表數據索引,如下圖

hash表對應的這個結構中包括了三個用於定位數據value的信息,分別是文件id號(file_id),value值在文件中的位置(value_pos),value值的大小(value_sz),於是我們通過讀取file_id對應文件的value_pos開始的value_sz個字節,就得到了我們需要的value值。整個過程如下圖所示:

由於多了一個hash表的存在,我們的寫操作就需要多更新一塊內容,即這個hash表的對應關系。於是一個寫操作就需要進行一次順序的磁盤寫入和一次內存操作。

另外,由於索引hash表是存放在內存中的,每次進程重啟時需要重建hash表,這需要整個掃描一遍所有的數據文件,如果數據文件很大,這將是一個非常耗時的過程。因此Bitcask模型中包含了一個稱作hint file的部分,目的在於提高重建hash表的速度

上面講到在old data file進行merge操作時,會產生新的data file,而Bitcask模型實際還鼓勵生成一個hint file,這個hint file中每一項的數據結構,與data file中的數據結構非常相似,不同的是他並不存儲具體的value值,而是存儲value的位置,這樣,在重建hash表時,就不需要再掃描所有data file文件,而僅僅需要將hint file中的數據一行行讀取並重建即可。大大提高了利用數據文件重啟數據庫的速度。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM