LSM Tree 數據庫底層索引

數據庫中非常常用的索引數據結構——B+ 樹,在過去很多年里它都是數據庫索引的首選實現方式,但是這種數據結構也并不是很完美。因為,每次修改數據都很有可能破壞 B+ 樹的約束,我們需要對整棵樹進行遞歸的合并、分裂等調整操作,而不同節點在磁盤上的位置很可能并不是連續的,這就導致我們需要不斷地做隨機寫入的操作,而隨機寫入的性能是比較差的,這個問題在寫多讀少的場景下會更加明顯。

LSM Tree(Log Structure Merge Tree)是比 B+ 樹更適合寫多讀少場景的索引結構,也廣泛應用在各大 NoSQL 中。比如基于 LSM 樹實現底層索引結構的 RocksDB、LevelDB。


LSM Tree 的實現原理:

LSM 樹包含了三個部分,memtable、immutable memtable、SSTable前兩個在內存中(使用預寫日志的機制來確保數據的持久性),最后一個在磁盤中。同樣,我們會先臨時地把數據寫在 memtable 中,然后在合適的時機刷入磁盤上的 SSTable 中。

1.Memtable

Memtable 顯然是內存中的數據結構,存儲的是近期更新的記錄值,可以用各種有序高效的數據結構來實現,比如跳躍表、紅黑樹,不過可以簡單的理解Memtable是一個 有序Map。


2.Immutable Table

在 Memtable 存儲的元素到達一個數量級之后(大小一般為虛擬內存的頁的倍數 4n KB),會把它固化成 immutable table,從字面上理解,就是不可變表。很明顯這就是 memtable 的拷貝操作,因為拷貝過程是需要時間的,但同時我們的系統很可能仍然在對外工作,所以創建副本可以很好的地幫助我們避免讀寫沖突競爭,從而避免阻塞,提高系統性能。


3.SSTable

SSTable 是整個 LSM Tree 的核心,畢竟我們的大部分數據都是存儲在磁盤上的,SSTable 就是在磁盤上做持久化的部分。本質其實很簡單,就是一段段按照 key 有序排列的鍵值對,而持久化數據到磁盤最高效的方式就是順序寫一遍(順序IO),每次內存中的數據immutable table,我們都一次性 dump 成磁盤上的一段自然是比較快的,這樣一段段的數據,我們就稱為一個個 segment。當然,后面存儲的段和前面存儲的段,key 可能是重復的,因為后面的段新一些,所以在有重復的時候,最靠后的段中的記錄值,就是某個 key 最新的狀態。

但很顯然,這樣的存儲會有很多問題,首先數據冗余很大,隨著時間推移,磁盤上就會有大量重復的鍵,其次我們需要遍歷每個有序的 segment,查看數據是否存在。隨著數據量增大,最壞情況下,要遍歷的 segment 會非常多,整個系統的查詢效率顯然是慘不忍睹的。

所以我們需要合并 segment,合并前老的 segment 長度都是一樣的且有序的,在 SSTable 的主流實現里,我們會把不同的階段被合并的 segment 放到不同的層中,并限制每一層數量,當某層 segment 超過一定數量,我們就會把它們刪除,合并出一個更大的 segment 放入下一層(低層中的 segment 是更新的記錄值,高層的則是更老的記錄值)。同時也會對相同的key進行最新值的覆蓋,以減少數據的冗余。

檢索的時候,我們只需要按照“內存 -> SSTable 第一層->SSTable 第二層”這樣的順序,去遍歷每層中不同段是否包含目標 key。每個段內都是有序存儲的,所以整體讀的時間復雜度也是可以接受的,確實可能會比 B+ 樹的查詢效率低一些,不過輔以布隆過濾器等手段,劣化也不會非常明顯,在許多讀寫比不到 1:10 的場景下,順序寫帶來的寫性能提升是非常令人滿意的。


總結自(極客時間-業務開發算法50講-黃清昊)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 0 前言 對于存儲介質為磁盤或SSD的數據庫,長期以來主流使用B+樹這種索引結構來實現快速數據查找。當數據量不太大...
    movee閱讀 7,343評論 1 8
  • 數據庫系統設計概述 世界上只有兩種開發人員,一種使用數據庫系統的,一種開發數據庫系統的。 數據是系統最重要的信息。...
    MageByte_青葉閱讀 852評論 0 0
  • LSM-Tree是什么 LSM-Tree(Log Structured Merge Tree),一種分層、有序、面...
    雁陣驚寒_zhn閱讀 1,431評論 0 2
  • 最近練手的項目里用到了LevelDB, 具有很優秀的存儲效率,DDIA中有介紹它底層是LSM-tree實現的,今天...
    芥川世之介閱讀 755評論 0 0
  • 一 背景 本來想寫點B+樹的,不過B+樹因為用在Mysql等關系型數據庫中,大家都比較了解了,而LSM樹這種索引設...
    堯字節閱讀 418評論 0 0