淺析日誌結構的存儲引擎(1)-bitcask

 

這系列文章主要是講key-value結構的存儲引擎,比如bitcask、sstable、LSM-tree等。不涉及內存型的key-value,比如redis。

 

一、數據寫入與查找

對於數據寫入磁盤,最簡單最快的方式就是順序寫入磁盤,用簡單追加日誌文件的方式(Append),就達到了性能的最高效。假設我們把key-value在文件中的offset也記錄下來,那麼我們就能從磁盤中查找到這對key-value。

二、數據查找的速度

假設我們先不考慮key-value的更新,數據寫完磁盤後,用哈希表的形式把key-value的offset放到內存,大家都知道哈希表(hash map)的查找時間複雜度是O(1),這時只需要一次磁盤尋址,就可以把value從磁盤加載到內存。如果那部分數據文件已經在文件系統緩存中,則讀取根本不需要任何的磁盤I/O。結構如下圖:

三、如何解決key更新的問題

上面已經講過,key-value用追加日誌文件的方式寫入,當更新一對key-value時,就會追加寫入一對新的key-value,而舊版的key-value不會被覆蓋。如何解決讀到最新的數據?這個也很好解決,只要保證讀取時,從最新寫入的文件偏移量中讀取即可。但是同樣的key,更新值使用追加的方式,又會帶來新的問題(假設key是電影名,value是播放次數,100萬次播放,就會產生100萬條記錄,其中只有1條是有效記錄,舊的版本都是廢棄的),這就會帶來磁盤空間快速消耗的問題。

四、數據壓縮和查找

一個好的解決方案是將日誌文件分解成一定大小的段,當文件達到一定大小時就關閉它,並將後續寫入到新的段文件中。然後在這些段上執行數據合併壓縮,壓縮是指丟棄重複的鍵,並且只保留每個鍵最新值,壓縮可以在後臺線程處理。如下圖,"new"這個key寫了5次,合併後只保留了最新值1082:

也可以將多個段合併成一個段,如下圖:

每個段都有自己的內存哈希表,用來保存全部的key和value偏移量。爲了找到key的值,首先檢查最新的段的hash map,如果鍵不存在,檢查第二新的段,以此類推。

五、侷限性

1,由於key需要全部放內存,當key越多,需要的內存資源越多。

2,不支持區間查詢,查找指定範圍的一批數據,需要全盤掃描。

3,進程重啓後,內存中的key就會丟失,需要重新加載。可以把哈希表提前備份到磁盤,這樣可以避免進程重啓時,需要全量掃描數據重建索引。

六、小結

以上就是bitcask的基本設計思想

 

參考《數據密集型應用系統設計》

原文出自:https://blog.csdn.net/daiyudong2020/article/details/104687575

end

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章