詳解資料庫儲存的資料結構LSM Tree

易鯨捷資料庫發表於2023-04-14

LSM-Tree全稱是Log Structured Merge Tree,是一種分層,有序,面向磁碟的資料結構。

LSM樹的定義

  1. LSM樹是一個橫跨記憶體和磁碟的,包含多顆"子樹"的一個森林。

  2. LSM樹分為Level 0,Level 1,Level 2 ... Level n 多顆子樹,其中只有Level 0在記憶體中,其餘Level 1-n在磁碟中。

  3. 記憶體中的Level 0子樹一般採用排序樹(紅黑樹/AVL樹)、跳錶或者TreeMap等這類有序的資料結構,方便後續順序寫磁碟。

  4. 磁碟中的Level 1-n子樹,本質是資料排好序後順序寫到磁碟上的檔案,只是叫做樹而已。

  5. 每一層的子樹都有一個閾值大小,達到閾值後會進行合併,合併結果寫入下一層。

  6. 只有記憶體中資料允許原地更新,磁碟上資料的變更只允許追加寫,不做原地更新。

  • 圖1中分成了左側綠色的記憶體部分和右側藍色的磁碟部分(定義1)。

  • 圖1左側綠色的記憶體部分只包含Level 0樹,右側藍色的磁碟部分則包含Level 1-n等多棵"樹"(定義2)

  • 圖1左側綠色的記憶體部分中Level 0是一顆二叉排序樹(定義3)。注意這裡的有序性,該性質決定了LSM樹優異的讀寫效能。

  • 圖1右側藍色的磁碟部分所包含的Level 1到Level n多顆樹,雖然叫做“樹”,但本質是按資料key排好序後,順序寫在磁碟上的一個個檔案(定義4) ,注意這裡再次出現了有序性。

  • 記憶體中的Level 0樹在達到閾值後,會在記憶體中遍歷排好序的Level 0樹並順序寫入磁碟的Level 1。同樣的,在磁碟中的Level n(n>0)達到閾值時,則會將Level n層的多個檔案進行歸併,寫入Level n+1層。(定義5)

  • 除了記憶體中的Level 0層做原地更新外,對已寫入磁碟上的資料,都採用Append形式的磁碟順序寫,即更新和刪除操作並不去修改老資料,只是簡單的追加新資料。圖1中右側藍色的磁碟部分,Level 1和Level 2均包含key為2的資料,同時圖1左側綠色記憶體中的Level 0樹也包含key為2的資料節點。(定義6)

LSM樹結構如下圖所示:

資料庫在執行寫操作時,先同時寫memtable與預寫日誌WAL。memtable寫滿後會自動轉換成不可變的(immutable)memtable,並flush到磁碟,形成L0級sstable檔案。sstable即有序字串表(sorted string table),其內部儲存的資料是按key來排序的,後文將其簡稱為SST。

執行讀操作時,會首先讀取記憶體中的資料(根據區域性性原理,剛寫入的資料很有可能被馬上讀取),即active memtable→immutable memtable→block cache。如果記憶體無法命中,就會遍歷L0層sstable來查詢。如果仍未命中,就透過二分查詢法在L1層及以上的sstable來定位對應的key。

隨著sstable的不斷寫入,系統開啟的檔案就會越來越多,並且對於同一個key積累的資料改變(更新、刪除)操作也就越多。由於sstable是不可變的,為了減少檔案數並及時清理無效資料,就要進行compaction操作,將多個key區間有重合的sstable進行合併。

LSM Tree的特性

插入操作

LSM樹的插入較簡單,資料無腦往記憶體中的Level 0排序樹丟即可,並不關心該資料是否已經在記憶體或磁碟中存在。該操作複雜度為樹高log(n),n是Level 0樹的資料量,可見代價很低,能實現極高的寫吞吐量。

刪除操作

LSM樹的刪除操作並不是直接刪除資料,而是透過一種叫“墓碑標記”的特殊資料來標識資料的刪除。

刪除操作分為:待刪除資料在記憶體中、待刪除資料在磁碟中 和 該資料根本不存在 三種情況。

 待刪除資料在記憶體中:

待刪除資料在記憶體中的刪除過程。我們不能簡單地將Level 0樹中的節點刪除,而是應該採用墓碑標記將其覆蓋。

待刪除資料在磁碟中:

待刪除資料在磁碟上時的刪除過程。我們並不去修改磁碟上的資料(理都不理它),而是直接向記憶體中的Level 0樹中插入墓碑標記即可。

待刪除資料根本不存在:

這種情況等價於在記憶體的Level 0樹中新增一條墓碑標記,場景轉換為情況3.2的記憶體中插入墓碑標記操作。

不論資料有沒有、在哪裡,刪除操作都是等價於向Level 0樹中寫入墓碑標記。該操作複雜度為樹高log(n),代價很低。

修改操作

修改操作都是對記憶體中Level 0進行覆蓋/新增操作。該操作複雜度為樹高log(n),代價很低。

LSM樹的增加、刪除、修改(這三個都屬於寫操作)都是在記憶體執行,完全沒涉及到磁碟操作,所以速度快,寫吞吐量高。

LSM Tree的優缺點

LSM樹將增、刪、改這三種操作都轉化為記憶體insert + 磁碟順序寫(當Level 0滿的時候),透過這種方式得到了無與倫比的寫吞吐量。

LSM樹的查詢能力則相對被弱化,相比於B+樹的最多3~4次磁碟IO,LSM樹則要從Level 0一路查詢Level n,極端情況下等於做了全表掃描。(即便做了稀疏索引,也是lg(N0)+lg(N1)+...+lg(Nn)的複雜度,大於B+樹的lg(N0+N1+...+Nn)的時間複雜度)。

同時,LSM樹只append追加不原地修改的特性引入了歸併操作,歸併操作涉及到大量的磁碟IO,比較消耗效能,需要合理設定觸發該操作的引數。

綜上我們可以給出LSM樹的優缺點:

:增、刪、改操作飛快,寫吞吐量極大。

:讀操作效能相對被弱化;不擅長區間範圍的讀操作; 歸併操作較耗費資源。

LSMTree的增、刪、改、查四種基本操作的時間複雜度分析如下所示:

總結

以上是對LSM樹基本操作以及優缺點的分析,我們可以據此得出LSM樹的設計原則:

  1. 先記憶體再磁碟

  2. 記憶體原地更新

  3. 磁碟追加更新

  4. 歸併保留新值

如果說B/B+樹的讀寫效能基本平衡的話,LSM樹的設計原則透過捨棄部分讀效能,換取了寫效能。該資料結構適合用於寫吞吐量遠遠大於讀吞吐量的場景。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026636/viewspace-2945717/,如需轉載,請註明出處,否則將追究法律責任。

相關文章