跳至主要內容
論文精煉 · Storage engine

The Log-Structured Merge-Tree (LSM-Tree)

把索引插入延後並批次化,交給層層串接的排序合併處理,將磁碟臂成本壓低近兩個數量級的磁碟索引結構。

作者Patrick O'Neil、Elizabeth O'Neil(UMass/Boston 數學與資訊科學系),Edward Cheng(Digital Equipment Corporation),Dieter Gawlick(Oracle Corporation) 發表於Acta Informatica 33,1996 年份1996
閱讀原始論文 PDF 所有論文

一口氣講完 — 整篇論文的濃縮

高插入率的 History 表與交易日誌需要即時索引,但在論文改寫的 TPC-A 例子裡,一個建在 Account-ID 串接 Timestamp 上的 B-tree,會在 Account 表原本就需要的每秒 2000 次隨機 I/O 之上再加 2000 次,磁碟臂數量因而翻倍,整體系統成本最多上升五成。LSM-tree 把「立即定位」換成「延後、批次定位」:每一筆索引項先寫進記憶體常駐的 C0 tree,完全不產生 I/O,再由一個持續繞行的 rolling merge 游標,把 C0 中已排序的區段掃進磁碟上的 C1 tree,讀寫一律以約 256 KBytes 的 multi-page block 為單位,並且永遠寫到磁碟上全新的位置。由此得到兩個相乘的節省:multi-page block 內的單頁 I/O 成本約只有隨機單頁 I/O 的十分之一,而每個 C1 leaf page 只花一次讀與一次寫,就能吸收 M 筆新項目。把結構推廣到 K+1 個元件、相鄰元件間維持等比的大小比例,就能在維持低合併 I/O 速率的同時,大幅縮小昂貴的記憶體元件。在論文的實算例子裡,B-tree 要價 56,400 美元,雙元件 LSM-tree 只要 11,400 美元;插入率提高十倍後,B-tree 要 506,400 美元,三元件 LSM-tree 仍只要 11,300 美元。

在這篇論文之前 — 它所降落的世界

1996 年,B-tree 是所有商用系統預設的磁碟索引;而在隨機鍵值上做一次 B-tree 插入,需要沿目錄層往下搜尋、再寫回被弄髒的 leaf,大約是 De + 1 次隨機頁 I/O,這種規模的索引其有效深度 De 通常是 2。Gray 與 Putzolu 的 Five Minute Rule 則定下了另一條路的經濟學:以 1995 年的價格,只有當一頁被引用的頻率高於大約每 60 秒一次時,買記憶體把它留住才划算——這個門檻已從 1987 年的五分鐘降下來,一部分因為記憶體變便宜,一部分因為大量生產的廉價磁碟出現。累積 20 天、共 576,000,000 筆的 Acct-ID 串接 Timestamp 索引佔 9.2 GBytes,攤在約 230 萬個 leaf page 上,任一頁平均每 2300 秒才因插入被碰一次,遠低於值得緩衝的門檻,也就是說每次插入真的都要跑兩趟磁碟。同一時期,Sagas、ConTracts 與 Escrow 這類長時間執行的 activity flow 系統,在很長的期間內產生龐大的日誌記錄,傳統上用來追蹤活躍日誌的記憶體常駐結構已經放不下。先前也有延後定位的設計——Time-Split B-tree、MD/OD R-tree、Differential File——但它們一律把那個小而新的元件當成磁碟常駐,這正是它們都沒能降低插入成本的原因。

問題 — 當時真正壞掉的地方

  • 在論文改寫的 TPC-A 例子中,為 History 表即時維護 Acct-ID 串接 Timestamp 的 B-tree 索引,會在 Account 表原本就需要的每秒 2000 次 I/O 之上再加 2000 次隨機 I/O,必須多買 50 支磁碟臂,等於讓應用的磁碟成本整整翻倍。
  • 由於 Acct-ID 是從一億個帳號中隨機抽取,每一筆新索引項幾乎都落在既有 230 萬個 leaf page 中任意的一頁上,緩衝管理員根本沒有局部性可以利用。
  • 依照 Five Minute Rule,這些 leaf page 平均每 2300 秒才被引用一次,遠不足以支撐常駐記憶體,因此每次插入都得付出一次頁讀取,以及穩態下的一次頁寫回。
  • 真正的瓶頸成本是磁碟臂而非磁碟容量:索引本身只需 9.2 GBytes 的容量,卻必須攤在足夠多的主軸上才撐得起所需 I/O 速率,買來的容量大半閒置。
  • 長時間執行的 activity flow 與工作流程系統,在很長的期間內累積大量日誌記錄,傳統用來追蹤活躍日誌的記憶體常駐結構已不可行,但這些日誌仍必須能被即時查詢。
  • 經典存取方法沒有一個逃得掉:B-tree、SB-tree、Bounded Disorder file 與 extendible hashing 都會把新項目立刻放到它最終的排序位置上——論文稱之為 Continuum Structure——因此每筆插入至少要兩次 I/O。

核心概念 — 主要貢獻,以及它們為何成立

延後且批次化的索引定位

LSM-tree 從不把新項目直接放到它最終該去的位置。一次插入只寫進記憶體常駐的 C0 tree,完全不花 I/O,這筆項目日後再與大批鄰居一起往外遷移。之所以行得通,是因為索引插入的成本幾乎全由磁碟臂租金決定,而一支替上百筆項目只移動一次的磁碟臂,攤到每筆的成本就便宜上百倍。論文特別強調:光延後還不夠,最初承接插入的元件必須「保證」常駐記憶體;若只是「有機會被緩衝」,效能就會退回每筆插入兩次 I/O——Time-Split B-tree 與 MD/OD R-tree 拿不到這個好處,原因正在此。

rolling merge(滾動式合併)

它不是週期性的重整,而是一個概念上的游標,持續在 C0 與 C1 相同鍵值範圍上繞行,以量化的 merge step 把項目從記憶體帶進磁碟元件。每一步從緩衝中的 emptying block 讀出一個 C1 leaf 節點,與對應範圍的 C0 項目合併,結果寫進 filling block;filling block 一填滿就寫到磁碟上全新的位置。游標走到最大鍵值後就繞回最小鍵值重新開始。因為整個掃描是有序且單向的,所有合併流量都是大塊循序 I/O 而非隨機頁 I/O;而且游標的尾端會一次釋放整個 block。

multi-page block 與 100% 填滿的節點

C1 有類似 B-tree 的目錄,但節點是 100% 填滿的,而且 root 以下依鍵值順序排列的單頁節點會連續放在約 256 KBytes 的 multi-page block 裡——這個手法取自 SB-tree。合併與長範圍檢索以整個 block 為單位讀寫;精確比對的查找則沿單頁節點下降,讓緩衝需求維持很小。把一次尋道與一次旋轉延遲攤到約 64 個頁面上,正是 block 內單頁成本只有隨機單頁十分之一的原因。全滿的填塞方式在容量上也贏過成長中的 B-tree——後者通常只有約 70% 的佔用率。

雙因子插入成本模型

論文把整個比較壓縮成一個比值:LSM-tree 插入成本除以 B-tree 插入成本,等於 K1 乘上 COSTpi/COSTP 再乘上 1/M,其中 K1 = 2/(De+1),約為 0.67。第一個因子是區塊 I/O 折扣,約 1/10,由磁碟力學決定,任何演算法都動不了。第二個因子是 batch-merge 參數 M,也就是平均有多少筆 C0 項目被併進一個 C1 leaf page,等於 (Sp/Se) 乘上 S0/(S0+S1),會隨記憶體元件變大而變大。兩者相乘通常帶來接近兩個數量級的改善;而這個模型也誠實地寫出自己的失效條件:一旦 M 低於 K1 乘 COSTpi/COSTP,就該改用普通的 B-tree。

多元件結構與最佳大小比例

在雙元件結構中要把 M 撐大,就得買昂貴的 C0;解法是在中間插入若干磁碟元件 C0、C1、……、CK,大小遞增,每一對相鄰元件之間都有各自非同步進行的 rolling merge。Theorem 3.1 證明:在最大元件大小 SK、記憶體大小 S0 與插入率 R 都固定時,總合併頁 I/O 速率 H 恰好在所有比值 ri = Si/Si-1 都等於同一個 r(也就是 SK/S0 的 K 次方根)時最小,此時 H = (2R/Sp) 乘上 (K(1+r) - 1/2)。批次效益因此跨層等比累乘,記憶體元件得以大幅縮小——論文的例子中,從兩個元件改成三個元件,S0 由 135 MBytes 降到 17 MBytes,總成本反而更低。這正是現代 leveled compaction 所實作的結果。

可合併操作:不只是插入

刪除同樣享有延後的好處:若鍵值不在 C0 中,就在該位置放一筆 delete node entry,記下要刪除的 RID;日後合併時兩者相遇,它會就地把真正的項目消滅掉。查找必須經過 delete node entry 過濾,而這很便宜,因為墓碑一定位在比目標更早的元件裡。對索引欄位的更新則視為一次刪除加一次插入。論文還定義了 predicate deletion:只要宣告一個述詞(例如「超過 20 天」),合併游標經過時就順手把符合的項目丟掉;以及 long-latency find:把一筆 find note entry 放進 C0,讓它隨游標往外走並沿途累積 RID,直到抵達最大的相關元件為止。

把索引問題重新表述為降低資料溫度

論文把一批資料的「溫度」定義為 H/S,即每 MByte 每秒的存取次數;冰點 Tf = COSTd/COSTP 之下是容量決定成本,沸點 Tb = COSTm/COSTP 之上則值得常駐記憶體——這是 Five Minute Rule 的直接推廣。用這套語言來說,LSM-tree 做的事就是降低實際磁碟存取率,也就是降低被索引資料的有效溫度。以邏輯插入率來看很「燙」的工作負載,換算成實體磁碟存取率只是「溫」的,於是 B-tree 會逼進記憶體的資料,在 LSM-tree 下可以留在磁碟上。把存取方法的選擇改寫成硬體採購的論證,才是這篇論文真正的修辭武器。

運作方式 — 具體的機制

插入路徑:先寫日誌,再進 C0

新的 History row 會先照常在循序日誌檔寫下一筆一般的交易插入記錄——本來就會寫,不需要為索引另外造日誌。索引項接著放進記憶體常駐的 C0,零 I/O 成本。C0 不必長得像 B-tree,因為它從不落到磁碟上,節點可以是任意大小,(2-3) tree 或 AVL tree 都很合適——沒有理由為了壓低樹高而犧牲 CPU 效率。當 C0 成長到門檻大小時,最左端一段連續的項目會被以批次方式一次刪除並交給 rolling merge,而樹只在整批處理完後重新平衡一次,不是每刪一筆就平衡一次。

一次 merge step 的解剖

游標在 Ci-1 有一個內元件位置,在 Ci 有一個外元件位置,兩者在 leaf 層以及沿途每一個目錄層都有對應位置。一個裝著 Ci leaf 的 multi-page block 被讀進 emptying block 緩衝區;項目與進來的區段合併後,由左至右寫進 filling block 緩衝區,該 block 填滿後寫到磁碟上一塊全新的空白區域,而不是覆蓋舊 block。Ci 的父層目錄節點在緩衝區中被更新以指向新 leaf,舊 leaf 則失效並從目錄中移除。留有殘餘是常態:一次 merge step 幾乎不可能剛好在新節點填滿的同時把舊節點清空,因此未滿的節點與 block 會留在緩衝區裡,整個結構本來就設計成能容忍這件事。在最一般的情形下,若刻意要把部分項目保留在 Ci-1,內外兩側都會各有一個 emptying block 與 filling block,同時牽動四個節點。

磁碟配置與查找路徑

每個磁碟元件都由頁面大小的節點組成類 B-tree 的目錄,差別在於 root 以下依鍵值順序排列的一串節點會共處於同一個 multi-page block,而目錄會記錄哪一串節點落在哪個 block,使整塊資料能以一次 I/O 讀寫。目錄節點在下列時機被迫寫到新的磁碟位置:其 multi-page block 緩衝區填滿、root 分裂使樹加深、或執行 checkpoint。精確比對的查找只走單頁節點,避開整塊讀取以壓低緩衝需求;長範圍檢索則使用整塊讀取。一次查找要依序搜尋 C0、C1,一路到 CK,一般情況下每個元件都得碰——相較 B-tree,每多一個磁碟元件大約多一次頁 I/O;論文的算法是省下約 6,400 美元的目錄緩衝,換來多一次讀取。

提早結束查找的三種方法

論文給了三種避免搜遍所有元件的辦法。其一,若鍵值的產生方式本身保證唯一(例如時戳必然相異),只要在較早的 Ci 找到相符值就可以收工。其二,若查找條件用的是很新的時戳,目標項目根本還來不及遷移到最大的元件。其三,合併時可以刻意把最近 tau_i 秒內插入的項目留在 Ci 而不往外推,於是只要記下每筆交易的開始時間,系統就能保證最近 tau_0 秒內開始的交易其全部日誌仍在 C0,完全不必碰磁碟——這讓 C0 真正扮演了近期資料的緩衝角色,也正是 UNDO 日誌索引之所以便宜的關鍵。

元件大小的決定

在穩定插入率 R(bytes/秒)與頁大小 Sp 之下,每個磁碟元件 Ci 貢獻 ri.R/Sp 次頁讀取(為了併入它)、(ri+1).R/Sp 次頁寫入(同一次合併的輸出),以及 R/Sp 次頁讀取(為了從它往外併),加總得到 H = (2R/Sp) 乘上(所有 ri 之和,再加 K - 1/2)。在所有 ri 之乘積等於 SK/S0 的限制下最小化這個式子,會強迫所有 ri 相等,也就是元件大小構成等比數列。總成本為 COSTm.S0 + max(COSTd.S1, COSTpi.H):縮小 S0 是拿昂貴的記憶體換便宜的磁碟,直到磁碟臂飽和為止;再縮下去就得把資料攤到更多主軸上,成本反而回升。雙元件的最佳解在 t 不大於 1 時沿 s = t,之後沿 s 等於 t 的平方根,最小成本為 2 倍的 (COSTm.S1)(2.COSTpi.R/Sp) 之平方根——它隨 R 的平方根成長,而 B-tree 是隨 R 線性成長。

並行控制

鎖定的單位是節點。必須協調三種實體衝突:查找碰到 rolling merge 正在改寫的節點;對 C0 的查找或插入碰到正要併往 C1 的那段範圍;以及較快的內側游標必須越過較慢的外側游標——因為從 Ci-1 往外遷移的速率永遠不低於從 Ci 往外遷移的速率。合併中的節點以寫入模式上鎖,查找則對存取路徑上的節點加讀取鎖,並在掃完 leaf 層項目後立刻釋放。最一般的情形下,游標同時對四個節點持有寫入鎖:內外兩側的 emptying 節點與 filling 節點;每當外元件的一個 emptying 節點被完全掏空時就釋放一次,這個量化的釋放時機正是讓一個游標超車另一個游標的窗口——被超越的游標其內元件位置會失效,必須重新定位。C0 內的鎖定方式取決於所選資料結構,例如對涵蓋合併範圍的某個 (2-3) 目錄節點以下整棵子樹加寫入鎖。論文刻意只處理多層鎖定中最底層的實體層,把 key range 鎖定與 phantom 問題留給別人。

checkpoint 與復原

復原直接沿用一般的交易插入日誌,把它們當成邏輯日誌來重建索引項,代價只是這些日誌要晚一點才能回收空間。在時刻 T0 執行 checkpoint 時,系統先做完所有進行中的 merge step 以釋放節點鎖,暫停新的插入,把 C0 寫到一個已知的磁碟位置,再把磁碟元件所有被弄髒的緩衝節點刷到磁碟,最後寫下一筆 checkpoint 日誌,內含最後一筆已建索引資料列的 LSN0、所有元件 root 的磁碟位址、每個 merge 游標的位置,以及目前 multi-page block 動態配置的狀態。重啟時載回 C0 與相關緩衝 block,把 LSN0 之後的日誌重放進 C0,再讓 rolling merge 重新啟動。這之所以安全,是因為合併結果永遠寫到磁碟新位置,復原所需的舊資訊從不被覆蓋,只在更新的寫入成功後才被標記失效。此外,emptying block 與新建節點都會立刻取得新的磁碟位址,父層目錄指標也在緩衝區中同步修正,讓 checkpoint 不必等待修正目錄的 I/O。

論文證明了什麼 — 量測數據與證明

  • 兩組獨立的磁碟量測都把區塊與隨機單頁的成本比 COSTpi/COSTP 定在約 1/10:1989 年 IBM 對 3380 磁碟上 DB2 的分析,單頁隨機讀約 20 ms,而 64 頁循序預取平均每頁約 2 ms;較新的 SCSI-2 讀取 4 KByte 單頁需 16 ms,讀 64 個連續頁共 95 ms,平均每頁約 1.5 ms。
  • 以 1995 年工作站價格 COSTm = 每 MByte 100 美元、COSTd = 每 MByte 1 美元、COSTP = 每秒每頁 25 美元、COSTpi = 2.5 美元計算,冰點為每秒每 MByte 0.04 次 I/O,沸點為 4 次;而 Five Minute Rule 的參考間隔在 4 KByte 頁面下算出 tau = 每次 I/O 62.5 秒。
  • 插入成本比值 K1 乘 COSTpi/COSTP 乘 1/M,在這種索引規模下 K1 約 0.67,通常帶來接近兩個數量級的改善;若索引項 16 bytes、每頁 200 筆、C1 是 C0 的 40 倍大,批次參數 M 就是 5。
  • Example 3.3,插入率 R = 每秒 16,000 bytes、索引 9.2 GBytes:B-tree 需要 50,000 美元的磁碟臂來供應每秒 2,000 次隨機 I/O,再加 6,400 美元記憶體緩衝 leaf 上一層,合計 56,400 美元;雙元件 LSM-tree 在 r = 460、C0 為 20 MBytes 時,磁碟 9,200 美元加記憶體 2,000 美元再加合併緩衝 200 美元,合計 11,400 美元。
  • Example 3.4,插入率提高十倍:B-tree 純粹為了供應每秒 20,000 次隨機 I/O 就得買 500 GBytes 磁碟,其中 491 GBytes 完全用不到,花費 506,400 美元;最佳的雙元件 LSM-tree 為 27,200 美元(13.5 GBytes 磁碟、135 MBytes 記憶體);三元件版本 r = 23、C1 為 400 MBytes、C0 為 17 MBytes,只要 11,300 美元。
  • Theorem 3.1 證明:固定 SK、S0 與 R 時,總合併頁 I/O 速率 H = (2R/Sp)(K(1+r) - 1/2) 恰在所有相鄰大小比值相等時最小;Theorem 3.2 則給出改為固定總大小 S 時的遞迴式 rK-1 = rK + 1、rK-2 = rK-1 + 1/rK-1,依此類推,論文並指出因為實用的 r 值多在 20 以上,兩者結果非常接近。

限制與取捨 — 論文自承的,以及後來被發現的

  • 論文自承:需要立即回應的查找會犧牲 I/O 效率——一次查找一般得搜遍所有元件,每多一個磁碟元件大約多一次頁 I/O,因此 LSM-tree 只適合插入遠多於檢索的場景;作者主張 History 表與日誌檔正是如此。
  • 論文自承元件數量有明確的實務上限。每多一個元件就多一份 rolling merge 的 CPU 成本與合併緩衝的記憶體成本——在常見的成本區間,後者甚至會蓋過 C0 本身的記憶體成本——而且每次查找都要多碰一個元件;當 r 降到 e = 2.71 時好處就用完了,作者因此判斷實務上大概最多只會看到三個元件。
  • 論文自承其成本分析只算插入:磁碟 I/O 容量全數配給 rolling merge,項目在抵達 CK 之前的刪除被忽略,如何在合併與查找之間平衡 I/O,被明白列為後續工作。
  • 論文自承 checkpoint 會造成一段可能不短的暫停,因為必須寫出 C0 與所有髒緩衝;游標互相超車後的重新定位、以及較高目錄層的合併演算法都留待日後處理;而且發表時既無正確性的形式化證明,也還沒有實作——整篇論證是分析式的,沒有任何實測系統。
  • 後續研究揭露了論文沒有建模的部分。LSM-tree 設計本身沒有 Bloom filter(論文只在討論 Differential File 時提到它),因此多元件的點查詢真的每層都得碰,直到 LevelDB 與 RocksDB 為每個 table 加上 filter 才改善;而 compaction 帶來的寫入放大、讀取放大與空間放大,以及它造成的尾端延遲尖峰,後來成為生產級 LSM 引擎最主要的工程難題,催生了 leveled 與 tiered 之爭,以及 bLSM、Monkey、Dostoevsky 等調校研究。

它後來變成什麼 — 繼承這個想法的系統

LSM-tree 成為寫入密集系統預設的儲存結構,它的術語如今就是整個產業的術語。Google 的 Bigtable 是最典型的具體化:memtable 扮演 C0,不可變的 SSTable 扮演磁碟元件,commit log 負責復原,minor、merging 與 major compaction 則扮演 rolling merge。LevelDB 與其後的 RocksDB 把它變成可重複使用的嵌入式引擎,也讓 Theorem 3.1 真正落地——leveled compaction 在相鄰層之間維持固定大小比例(預設為 10),正是論文證明為最佳的等比數列——同時加上每個 table 的 Bloom filter,緩解論文自己承認的查找代價。Apache HBase 與 Apache Cassandra 經由 Bigtable 與 Dynamo 繼承了這套設計,並繼續擴散到 ScyllaDB、InfluxDB 的 TSM 引擎、MongoDB 的 WiredTiger LSM 選項,以及透過 RocksDB 與 Pebble 的 CockroachDB 與 TiDB;Lucene 的 segment 合併則是近親。論文的成本框架比它的硬體活得更久:把磁碟臂換成 SSD 的寫入壽命,同一套論證就推出了驅動現代 compaction 研究的寫入放大分析,以及 RUM conjecture 的讀取/更新/記憶體三角取捨。連名字本身也一般化了——今日的 LSM-tree 指的是一整個設計家族,而非論文當年真正分析的雙元件與三元件結構。

論文原文 — 逐字引用

“The LSM-tree uses an algorithm that defers and batches index changes, cascading the changes from a memory-based component through one or more disk components in an efficient manner reminiscent of merge sort.(中譯:LSM-tree 使用一種延後並批次化索引異動的演算法,讓這些異動以近似合併排序的高效方式,從記憶體元件層層串接到一個或多個磁碟元件。)”

摘要(Abstract)

“The idea of always writing multi-page blocks to new locations was inspired by the Log-Structured File System devised by Rosenblum and Ousterhout [23], from which the Log-Structured Merge-tree takes its name.(中譯:永遠把 multi-page block 寫到新位置的想法,靈感來自 Rosenblum 與 Ousterhout 設計的 Log-Structured File System,Log-Structured Merge-tree 的名字也由此而來。)”

§2.1

“In these cases, the data is hot in terms of logical access rate (inserts/sec) but only warm in terms of physical disk access rate because of the batching effect of the LSM tree.(中譯:在這些情況下,就邏輯存取率(每秒插入數)而言資料是燙的,但因為 LSM-tree 的批次效果,就實體磁碟存取率而言它只是溫的。)”

§6

術語 — 依本篇論文的用法

LSM-tree
由兩個以上大小遞增的樹狀元件 C0 到 CK 組成的磁碟索引,其中 C0 常駐記憶體、其餘常駐磁碟,索引項透過 rolling merge 逐層往外遷移。
C0 component
最小且常駐記憶體的元件,以零 I/O 成本吸收所有插入。因為它從不落到磁碟,不必是 B-tree;論文建議用 (2-3) tree 或 AVL tree。
C1 component
常駐磁碟的較大元件。它有類似 B-tree 的目錄,但節點 100% 填滿,且 root 以下的節點序列被緊密塞進連續的 multi-page block,以有效使用磁碟臂。
Rolling merge(滾動式合併)
持續在背景進行的程序:一個概念上的游標以量化的 merge step 繞行兩個相鄰元件相同的鍵值範圍,把項目往外推,走到最大鍵值後再繞回最小鍵值。
Multi-page block
一段連續的頁面大小節點,論文設想約 256 KBytes,以單一單位讀寫,讓尋道時間與旋轉延遲攤提到約 64 個頁面上。
Emptying block 與 filling block
每一層夾在合併游標兩側的一對緩衝區:emptying block 存放游標尚未走到的舊節點,filling block 累積合併輸出,填得夠滿後寫到磁碟上的新位置。
Batch-merge 參數 M
rolling merge 期間平均併入每個單頁 C1 leaf 節點的 C0 項目數,等於 (Sp/Se) 乘上 S0/(S0+S1)。它是 LSM-tree 勝過 B-tree 的兩個因子中「批次」的那一半。
資料溫度(H/S)
每 MByte 儲存資料每秒的頁面存取次數。低於冰點 Tf = COSTd/COSTP 時成本由容量決定;高於沸點 Tb = COSTm/COSTP 時就該常駐記憶體;LSM-tree 的作用就是降低索引的有效溫度。
Continuum Structure
論文為「會把新插入項目立即放到它在既有項目中最終排序位置」的存取方法所取的名字。B-tree、SB-tree、Bounded Disorder file 與 extendible hashing 都屬此類,因此每筆插入都至少要兩次 I/O。

在時間軸上的位置 — 這篇論文在整段故事中的座標

在時間軸上查看