資料庫管理-第127期 LSM Tree(202301225)

yhw1809發表於2023-12-25

資料庫管理-第127期 LSM Tree(202301225)

說起分散式資料庫,繞不開的一個話題就是LSM Tree,全稱為log-structured merge-tree,回到呂海波老師授權過的那句話“沒搞過Oracle的,但又是資料庫圈裡的人,特別做資料庫開發的,對Oracle的印象就是:集中式、落後、舊時代的產物,超過Oracle很簡單,基於Poxos/Raft,隨便上個分散式就可以了。如果再實現個LSM Tree,那就超過Oracle太多了。”可見LSM Tree對於分散式資料庫是很重要的一個東西,無論是國外的HBase、Cassandra、LevelDB、RocksDB等,還是國內較為出名的OceanBase、TiDB等,都是使用LSM Tree來組織資料。

1 基本

LSM Tree和B+ Tree是資料庫建立block(塊)的時候提到的兩種基礎資料結構。B+ Tree一般用於較少查詢和插入時間的場景,而LSM Tree則用於寫壓力非常大而讀要求不是那麼高的場景。
LSM Tree並非是一個所謂的新技術,從維基百科來看這是一個誕生於1996年的技術,較早發表用於具體技術則是2006年Google發表的論文《Bigtable: A Distributed Storage System for Structured Data》,這篇論文也被譽為分散式資料庫開山鼻祖之作,後面很多分佈資料庫也都是基於這一篇論文的理論建立起來的。

2 機制

LSM Tree的出現是為了大資料量的OLAP場景,其最大的機制也可以說是優勢是可以充分利用磁碟順序寫的優勢而帶來非常強大的資料寫入效能,當然在查詢這塊犧牲了一定效能一般來說是慢於B Tree,當然這個效能也是可以接受的。而隨著記憶體與SSD價格的持續走低以及容量的極大提升,基於LSM Tree的資料庫讀效能也有了顯著提升。
一個簡單版本的LSM Tree包含兩層類似於樹狀的資料架構:

  • Memtable(記憶體表)完全駐留在記憶體中(定義為T0元件)
  • SSTable(Sorted String Table)儲存在磁碟上(定義為T1元件)

20231225-fad65824-5c1e-4b11-9c52-47bc7c3c9b55.png

新紀錄被插入到Memtable中(T0元件)。如果插入導致T0元件超過一定的大小閾值,則從T0中刪除一個連續的條目段,並將其合併到磁碟上的SSTable(T1元件)中。

3 元件

LSM Tree主要使用3個元件來最佳化讀寫操作:

Sorted String Table (SSTables):

資料按排序順序排序的,因此無論何時讀取資料,在最壞的情況下,其時間複雜度將為O(Log(N)),其中N是資料庫表中的條目數。

20231225-2dae0e21-6779-4bb5-b8e0-7b15e42452c3.png

Memtable:

這是一個記憶體結構;
以排序方式儲存資料;
作為回寫(Write-Back)快取;
當到達一定大小時將作為SSTable刷入資料庫;
當磁碟中SSTable的數量增加時,如果某些key不存在於記錄中時:

  • 要查詢這些key,需要讀取所有SSTable,這增加了讀取時間的複雜度
  • 為了克服這個問題,Bloom filter出現了
  • Bloom filter是一種節省空間的資料結構,它可以告訴我們記錄中是否缺少key,準確率為99.9%
  • 要使用此filter,我們可以在寫入資料的時候向其新增記錄,並在讀取請求開始時檢查key,以便在請求第一次出現時更有效地服務請求

20231225-d9845de1-cf8c-413b-88e9-737a1acc375d.png

Compaction:

直接翻譯過來就是壓實:
磁碟中以SSTable的形式儲存資料時,假設有N個SSTable,每個表的大小為M;
最壞情況下,讀取時間複雜度為O(N* Log(M)),因此,隨著SSTable數量的增加,讀時間複雜度也會增加;
此外,當我們只是重新整理資料庫中的SSTable時,相同的Key存在於多個SSTable中;
這時候Compactor就能發揮作用,compactor在後臺執行,合併SSTable並刪除相同的多行,並新增最新資料的新鍵,並將它們儲存在新的合併/壓縮的SSTable中。

20231225-96073b78-8c11-454d-b6fa-ca23772fcf83.png

20231225-aa792988-eef8-451b-a053-34c501fd07e5.png

正是這一元件,許多基於LSM Tree的分散式資料庫也在標榜自己在儲存側的壓縮能力,可以節省儲存成本。

4 問題

LSM Tree既然有較強的寫入響應能力,儲存節省能力,那麼LSM Tree就沒有缺點麼?

  • 還是借用呂海波老師的總結:“LSMTree最主要的問題,它是針對OLAP。底層Skiplist,鎖的粒度要麼太細,鎖太多。要麼鎖粒度太粗,鎖一大段連結串列。傳通架構,鎖就在塊上,塊上加個Pin,比Skiplist的併發性要好。”(說真的這句話看的不是太明白)
  • 讀效能偏低,但是在強大硬體和分散式MPP加持下也能帶來不錯的讀效能
  • 寫放大,還是那句話,NVMe SSD上那都不是事
  • 延遲合併帶來的不一致,特別是分散式架構同分片不同節點合併進度不同,可能導致連續兩次在不同節點查詢的結果不一致,當然這些都是可以透過一些技術手段解決的
  • 等等等等

總結

這不是我一個擅長的領域,以前沒有接觸過,也是翻了不少英文文件來寫這一篇文章,可能還有些東西是不對的,也是一種嘗試吧,也想著去看看國產分散式資料庫引以為傲的底層。
老規矩,不知道寫了些啥。

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

相關文章