The Log-Structured Merge-Tree(譯):下

me_lawrence發表於2015-09-24

http://duanple.blog.163.com/blog/static/7097176720123202219903/

4.Concurrency and Recovery in the LSM-tree

本節我們來研究下用於LSM-tree併發訪問和恢復的技術。為此,我們需要更深入地描述出rolling merge過程。我們將該併發訪問和恢復演算法正確性的形式化證明作為以後的工作,目前只是在此處簡單地描述下它們的具體過程。

4.1 Concurrency in LSM-tree

通常,一個具有C0,C1,C2…Ck-1Ck K+1個元件的大小不斷增長的LSM-tree,其中C0元件是放到記憶體中,其他元件都是磁碟駐留的。當Ci-1大小超過其閾值時,會由(Ci-1,Ci)之間的非同步的rolling merge過程負責將記錄從小的元件移到更大的元件中。每個磁碟元件都是由以B-樹型別的結構組織的page-sized的節點組成,同時在根節點下的各層的節點都是按照key的大小順序排列的,同時這些節點又會被放置到muti-page block中。該樹結構中的目錄資訊可以對使用者訪問所需經過的節點進行指引,同時還會標識出某muti-page block包含了那些頁面節點(single page nodes)。在大多數情況下,每個muti-page block都裝滿了頁面節點(single page nodes),但是也有些情況一個muti-page block只有少數的節點組成。在這種情況下,LSM-tree的活動節點將會由該muti-page block的一個連續的頁面集組成,同時它們也不一定是該block開始的那部分頁面。除此之外,LSM-tree元件的結構與[21]中的SB-tree結構並無二致,讀者可以參考該論文以獲取更多細節。

 

在執行等值匹配查詢時,磁碟元件Ci的一個節點可能是存在於單獨的一個記憶體頁中,或者是通過它所在的muti-page block而快取在記憶體中。一個muti-page block要麼是因為一個long range查詢要麼是因為rolling merge遊標正在穿過該block。在任何情況下,所有未被鎖住的Ci元件的節點都是可以始終被訪問的,磁碟訪問也可以執行以定位記憶體中的節點,即使該節點是正在進行rolling mergemuti-page block的一部分。考慮到各種因素,針對LSM-tree的併發訪問方法必須解決如下三種型別的物理衝突:

1. 查詢操作不能同時去訪問另一個程式的rolling merge正在修改的磁碟元件的節點內容

2.針對C0元件的查詢和插入操作也不能與正在進行的rolling merge的同時對樹的相同部分進行訪問

3.Ci-1Cirolling merge的遊標有時需要越過從CiCi+1rolling merge的遊標,因為資料從Ci-1移出速率>=Ci移出的速率,這意味著Ci-1所關聯的遊標的迴圈週期要更快。因此無論如何,所採用的併發訪問機制必須允許這種交錯發生,而不能強制要求在交會點,一個程式(移出資料到Ci的那個)必須阻塞在另一個程式(Ci移出資料的那個)之後。

 

節點是LSM-tree中用於避免基於磁碟的元件的併發訪問衝突的加鎖單位。正在因rolling merge而被更新的節點會被加上寫鎖,同時正在因查詢而被讀取的節點將會被加上讀鎖。同時用於防止死鎖發生的目錄鎖機制也已經被充分研究過(比如,參見[3])C0中所採用的鎖機制則取決於所採用的資料結構。比如,在(2-3)-樹的情況下,我們可以用寫鎖鎖住一個包含了mergeC1中的某個節點的受影響的邊界內的所有記錄的(2-3)樹目錄節點下的子樹;同時用讀鎖鎖住查詢操作所涉及的查詢路徑上的所有節點,這種不同型別的訪問就是互斥的。同時與[28]類似,我們只考慮在最底層的多級鎖機制上的併發機制。關於更抽象的鎖,比如用於提供事務隔離性的key range鎖,以及關於phantom update的問題,請參考[4],[14]的討論。只要正在被查詢的葉級節點被掃描後讀鎖就會釋放。在遊標下的節點的寫鎖,在節點被merge到更大的元件後也會被釋放。這就為long range find或者是讓一個更快速的遊標越過一個慢速遊標,這樣就能解決上面提到的第3點。

 

假設我們正在執行一個在兩個磁碟元件間的rolling merge,將記錄從Ci-1(又稱為該rolling merge過程的內元件)移到Ci(又稱為該rolling merge過程的外元件)Rolling merge遊標總會有一個準確的位於Ci-1的葉節點的內元件位置,它會指向將要被移出到Ci的下一條記錄,同時在Ci-1的更高層的目錄上沿著到達該葉子節點的訪問路徑都有一個對應位置。同時在Ci元件的葉子節點及到達該葉子節點的訪問路徑中,該遊標也有一個外部元件位置,該位置也對應著將要參與到merge中的那條記錄。在merge遊標穿過外部和內部元件的後續記錄時,由該merge過程新建立出來的葉子節點將會按照從左到右的順序立即放置到新的快取中的multi-page block中。因此在當前遊標位置附近的Ci元件中的節點通常會被分割到記憶體中的兩個未滿的multi-page block中:”emptying”block(記錄已經用盡但是仍包含一些當前遊標未到達的資訊)”filling” block(反映了此刻的merge結果,但是還未全滿所以未被寫到磁碟)。為了能夠併發訪問,”emptying”block”filling” block都包含整數個C1樹中的page大小的節點,同時這些節點都是駐留在記憶體中的。在merge步驟中的操作對節點進行重組時,相關的節點會被加上寫鎖,以阻止對這些記錄的其他型別的併發訪問。

 

rolling merge的最普通實現方式中,我們可能希望保留Ci-1元件中的某些記錄,而不是將遊標所經過的所有記錄都移出到Ci中。在這種情況下,merge遊標附近的Ci-1元件中的節點依然會被分到記憶體中的兩個multi-page block中,包含了merge遊標還未到達的Ci-1的節點的”emptying”block,以及從左到右放置的,由merge遊標最近經過的和仍然要保留在Ci-1中的節點組成的”filling” block。在最常見的情況下,merge遊標的位置一次將會影響四種不同的節點:在”emptying”block中的內元件和外元件節點(對於它們來說,merge即將進行),在” filling”block中的內元件和外元件節點(對於它們來說,隨著游標的行進,新的資訊正被寫出)。很明顯,在某個時刻這四種節點可能都處於未滿的狀態,對於包含它們的block來說也是這樣的。在merge真正修改節點結構時,會在這四個節點上加上寫鎖,同時會在特定的時間會釋放這些鎖以允許更快的遊標來超過它;我們會在當外元件的”emptying”block中的節點已經完全被用盡,而其他三個節點還很空的時候對這些鎖進行一次釋放。這是可以的,因為我們可以在一個節點還很空以及blocks還很空的樹進行所有的訪問操作。一個遊標越過另一個的情況需要仔細考慮,因為通常被繞開的rolling merge在它的內元件中的遊標位置將會變得無效,同時這就要求能夠重新調整遊標。同時上面的這些,也必須應用到兩個元件的上層目錄節點。通常上層目錄節點可能不是駐留在記憶體中的,這樣就需要使用一個稍微不同的演算法,但是在任意時刻都還會有filling nodeemptying node。我們將這些複雜的需要考慮的地方留到以後的工作中,在實現一個真正的LSM-tree後將會提供更多的經驗。

 

目前為止,我們還沒有考慮從C0C1的這一個特殊的rolling merge過程。實際上,與基於磁碟的元件間的merge相比,這個是相對簡單的。與其他的merge步驟一樣,需要一個單獨的CPU來負責該任務,這種其他的訪問因寫鎖所耽誤的時間就會盡可能的少。參與mergeC0記錄的range必須預先計算,同時像前面所說的那樣,需要提前在該記錄邊界上加上一把寫鎖。除此之外,還可以通過批量從C0元件中刪除記錄來節省CPU時間,這樣就不需要在每條記錄刪除後進行一個rebalance;在merge步驟完成之後,再對C0進行完整的調整。

4.2 LSM-tree中的恢復

當新的紀錄被插入到LSM-treeC0元件中後,rolling merge程式會將紀錄逐步遷移到後面更大的元件中,這項工作是發生在記憶體中的multi-page block上。由於在記憶體中快取了一些變更,這樣在它寫入到磁碟之前對於系統失敗來言它就不是安全的。我們就面臨了一個經典的恢復問題:重構那些已經存在於記憶體中的而在系統crash丟失的內容。正如我們在第2章的開頭提到的,我們不需要建立特殊的日誌來恢復新建立的這些記錄上的索引值:針對這些新記錄的事務型插入日誌已經被常態性地寫出到一個順序性的日誌檔案中,因此只需要簡單地將這些插入日誌(日誌裡包含了所有field的值插入記錄所對應的RID)作為索引值恢復的基礎即可。這種用於索引恢復的新方式必須內建到系統恢復演算法中,同時它也會影響到對於這種事務型插入歷史日誌的儲存空間回收時間,在恢復發生時回收會被延遲。

 

對於LSM-tree的索引恢復來言,最重要的是要仔細定義checkpoint的格式,以及需要知道從順序型日誌的何處開始,如何回放後續的日誌,從而能夠準確地重現那些需要恢復的針對索引的更新。我們採用瞭如下的模式。當在T0時刻啟動了一個checkpoint後,我們會完成所有正在進行的merge步驟,保證所有節點的鎖會被全部釋放,然後會將所有的新記錄的插入延遲直到checkpoint完成;與此同時,我們會通過下面的步驟建立一個LSM-tree checkpoint

 

l  C0元件的內容寫入到一個已知的磁碟位置;之後,針對C0元件的記錄插入就又可以開始了,但是merge步驟將會繼續被延遲

l  將所有磁碟元件在記憶體中的髒頁flush到磁碟

l  建立一個具有如下資訊的特殊的checkpoint日誌:

n  日誌序列號,LSN0,即T0時刻最後插入的索引行

n  所有元件的根節點的磁碟地址

n  上面這些元件中的所有merge遊標的位置

n  當前關於新的multi-page block的動態分配資訊

 

一旦checkpoint資訊被存入磁碟,就可以恢復LSM-tree的正常操作了。在crash發生或者重啟時,就可以找到這個checkpoint,將儲存過的元件C0以及其他元件需要進行rolling merge的快取的block內容載入回記憶體。然後,從日誌中LSN0之後的第一個LSN開始讀入記憶體,將它們相關聯的索引值加入到LSM-tree。在進行checkpoint時,包含了所有索引資訊的所有磁碟元件的位置資訊已經被記錄到checkpoint日誌中。這些資訊都還沒有被後續的multi-page block的寫入擦除,因為這些新的寫入在checkpoint過時之前,總是會被安排到新的位置上。我們開始恢復索引行的插入日誌,將新記錄加到C0元件;此時,rolling merge過程也重新開始,會覆蓋在該checkpoint之前寫入的那些multi-page block,但是隻有當所有最近插入的行已經被索引及恢復完成後,所有的新索引值才會恢復。

 

這個恢復方法很明顯是可以工作的,唯一的缺點在於各種發生在checkpoint執行時的磁碟寫入操作可能會經歷一個比較大的暫停。但是這個暫停並不是特別嚴重,因為當我們將C0元件快速寫入磁碟後,就可以恢復針對C0的插入;這可能導致新插入到C0中的索引值被merge到更大的磁碟元件的時間有所延遲。一旦checkpoint完成,rolling merge過程就可以繼續幹活。需要注意的是,上面提到的checkpoint日誌裡的最後一類資訊“當前關於新的multi-page block的動態分配資訊”。是因為在crash發生時,我們需要知道對於我們的動態磁碟儲存分配演算法來說,在恢復時哪些multi-page block是可用的。這個問題並不難解決;實際上[23]解決了一個關於垃圾收集更負責的問題。

 

關於恢復的另一個細節是如何處理目錄資訊。需要注意在rolling merge過程中,每當一個multi-page block或者一個高層目錄節點被磁碟中讀入以清空,它必須立即安排一個新的磁碟位置以應對checkpointemptying完成之前發生的情況,同時剩餘的快取資訊必須強制寫到磁碟。這意味著指向下層emptying節點的目錄節點必須立即修正以指向新的節點位置。類似地,我們必須立即為新建立的節點安排一個磁碟位置,這樣樹中的目錄節點就能夠立即指向對應的磁碟位置。每時每刻,我們都要確保那些包含指向被rolling merge快取的底層節點的指標的目錄節點也已經被快取;只有通過這種方式,我們才能迅速做出必要的修改以保證checkpoint不會因等待修正目錄節點的IO而被掛起。此外,在checkpoint發生只之後,以及multi-page block被讀回記憶體以繼續rolling merge時,所有相關的blocks必須被安排一個新的磁碟位置,因此所有指向附屬節點的目錄指標都必須被修正。這聽起來好像需要大量的工作,需要注意的是實際上這不會產生額外的IO需求,同時每個快取的block所涉及的指標數大概是64。另外假設checkpoint的頻率只需要保證恢復時間不會超過數分鐘即可,這些修改將會平攤到大量的被merge的節點上;這也意味著兩個checkpoint之間大概相隔數分鐘。

5. 與其他訪問方式的價效比對比

在例1.2中,我們考慮了針對History檔案上的Acct-ID||Timestamp索引的B-樹實現,因為它是用於商業系統中的最常見的基於磁碟的訪問方式。現在我們希望說明的是,不存在一個可以提供更好的IO效能的磁碟索引結構。為了說明這一點,我們論述如下。

 

假設我們正在處理一個任意的索引結構。假設索引具有20天的生命週期,並以每天8小時每秒1000條記錄的速率產生,索引條目的大小為16位元組(4位元組用於Acct-ID8位元組用於Timestamp4位元組用於History表的RID),這就意味著將會有9.2GB的記錄規模,在不存在空間浪費的情況下大概要2.3million4KB索引頁面。這些結論適用於任何一種索引模式。B-樹具有一些葉子節點,以及上層目錄節點帶來的空間浪費,但是一個可擴充套件的hash表可能會有不同程度的空間浪費,同時也沒有目錄節點,但是這兩種結構都必須能夠放得下上面提到的9.2GB的記錄資料。現在如果我們要將一條新的索引記錄插入到索引結構中,需要計算出該記錄需要被插入到那個頁面中並保證該頁面已經在記憶體中。自然地引出了一個問題:新插入的記錄通常是不是可能會被放置到現有9.2GB索引記錄的中間的任意位置?對於大多數經典訪問結構來說,答案是肯定的。

 

定義5.1 如果一個基於磁碟訪問方式的索引結構能夠為它的新插入的索引記錄基於Key-value的最終排序規則,即時地安置到現有的記錄中,我們就認為它具有連續性結構(Continuum Structure)這一屬性。

 

下面的TPC benchmark應用中的Acct-ID值是從100,000,000個可能取值中隨機生成的。根據定義1.1,針對Acct-ID||Timestamp索引的每個新插入的記錄將會被放置到現存記錄組成的2.3million頁面中非常隨機的一個位置上。比如對於B-樹來說,總共576,000,000的總記錄數,對於每個Acct-ID來說將會包含大概5.76(5.76=576,000,000/100,000,000)個記錄;可假定具體相同Acct-ID的記錄具有不同的時間戳。每個新插入的記錄將會被放置到具有相同Acct-ID的記錄的右側。但是這仍然還是具有100,000,000個隨機選擇地插入點,這也意味著每個插入將會隨機地落入現有的2.3millionpage中。與之相比,在一個可擴充套件hash模式[9]中,新的記錄的排列規則是根據從Acct-ID||Timestamp計算出來的hash值進行的,很明顯這與將一個新記錄放到現有記錄中是類似地。

 

2.3millionpage是一個能夠容納下9.2GB大小的記錄的Continuum Structure的最小可能值了。假定每秒1000個插入,那麼這樣一個結構的每個page大概需要間隔2300秒才會被訪問一次;根據五分鐘法則,將所有的page快取起來是不划算的。如果我們考慮像Bounded Disorder檔案[16]用更大的節點來儲存記錄,這不會帶來什麼好處,是因為儘管訪問頻率變大,但是快取節點的記憶體開銷也在變大,這兩者相互抵消了。通常,一個page會因為某條記錄的插入而讀入記憶體,後面又會因為為了給其他page騰出空間而擠出記憶體。在事務型系統中,在將磁碟page從記憶體清除之前原地更新,這種更新會對每個索引插入產生額外的一次IO。因此可以這樣說,對於不會延遲更新的Continuum Structure來說針對每個索引插入將會需要至少兩個IO操作,這與B-樹基本上是一致的。

 

大部分現有的基於磁碟的訪問方式都屬於Continuum Structure,包括B-[5],以及它的很多變種比如SB-[21]Bounded Disorder檔案[16],各種hash模式比如可擴充套件hashing[9],以及很多其他型別。但是,也有一些訪問方式會將它們的記錄從某一部分遷移到另一部分:KolovsonStonebrakerMD/OD R-樹,LometSalzburgTime-Split B-([17],[18])Differential File[25]也會先將變更收集到一個小的元件中,然後將更新應用到全域性結構中。我們下面會稍微深入地解釋下這些結構。

 

首先我們來分析下為何LSM-tree可以在某些情況下降低近兩個數量級的磁碟磁臂負載,而在IO效能上完勝Continuum StructureLSM-tree的優勢主要源於如下兩個因素:(1)能夠保證元件C0是記憶體存放的,(2)細緻的延遲放置策略。原始插入可以作用於一個基於記憶體的元件是很關鍵的。在Continuum Structure上的新記錄的插入需要兩次IO原因是:本身索引大小沒法很經濟地快取在記憶體中。如果LSM-treeC0元件的記憶體駐留屬性是無法保證的,僅僅是一種概率上的,隨著記憶體駐留情況的惡化,隨著新記錄插入所引起的IO開銷的增加將會導致LSM-tree效能的退化。在保證初始插入不會產生任何IO的情況下,第二個因素為LSM-tree提供了更高效能的支援。一個經過仔細設計的延遲放置策略,可以將C0的大小有效地控制在合理地範圍內。實際上,多元件LSM-tree提供了一系列地延遲放置策略來最小化總開銷。

 

Time-Split B-tree

 

我們先來看下LometSalzburgTime-Split B-tree(TSB-tree)TSB-tree是一個二維搜尋結構,它通過時間戳和keyvalue兩個維度來定位記錄。每當具有給定keyvalue值的記錄被插入時,老的那條記錄就會變成過時的;然而會儲存一條記錄的所有歷史狀態,無論是過期還是未過期的,都會被索引。當一個新記錄被插入到TSB-tree中的當前節點時,如果該節點空間不足,它可以根據key-value或者時間戳進行分裂,具體取決於環境設定。如果節點是根據時間t進行分割的,那麼時間戳小於t的所有記錄將會進入該次分裂的歷史節點中,在時間t之後的那些記錄則會作為當前節點。最終那些過時的記錄將會被遷移到一個廉價的write-once儲存裝置中。所有的當前記錄和當前節點存於磁碟中。

 

可以看到TSB-tree的這個模型與我們的模型有些不同。在具體相同Acct-ID的記錄被寫入後,我們不會對現存的老的記錄做任何地過期假設。很明顯,TSB-tree的當前節點集承擔著延遲更新到長期儲存元件的角色。但是當前tree不會像LSM-treeC0那樣,被保證儲存在記憶體中。實際上,當前tree是基於磁碟的,而歷史tree是存於write-once儲存裝置的。沒有證據表明TSB-tree可以提高插入效能,它的設計目的在為整個時間軸上的所有記錄提供一個歷史索引。並不保證新的插入一定會發生在記憶體中,因此每次記錄插入會需要兩次IO

 

MD/OD R-tree

 

KolovsonStonebrakerMD/OD R-tree[15],與TSB-tree不同,它使用了一個二維訪問模式(R-tree) 的變種來通過時間區間和keyvalue來索引歷史記錄。MD/OD R-樹中引入的這個R-tree變種是跨越磁碟(MD)和光碟(OD)的;最終的目的,與TSB-tree類似,是要將過期記錄移到一個儲存在廉價write-once光碟儲存裝置上的具有葉子頁面和目錄頁面的歸檔R-tree上進行儲存。這種遷移是通過VCP(Vacuum Cleaner Process)進行。但磁碟上的R-tree索引到達一定閾值,VCP會將其中一部分最老的葉子節點移到光碟上的R-tree中。與TSB-tree類似,MD R-tree存於磁碟元件,OD R-tree存於write-once儲存裝置,同時也沒有證據表明MD/OD R-tree可以提高插入效能。很明顯OD中排除了rolling merge技術。由於並不保證新的插入一定會發生在記憶體中,因此每次記錄插入也會需要兩次IO

 

Differential File

 

Differential File[25]以一個長期保持不變的主資料檔案作為起點,新增加的記錄會被放置到一個稱為Differential File的特殊區域。在未來的某個時刻,它將會與主資料檔案進行合併,之後重新產生一個新的Differential File。這篇論文的很多內容都是關於更小的動態區域的優勢以及避免重複訪問的方法,因為根據唯一記錄識別符號的查詢首先需要查詢differential 檔案(通過某些索引),然後查詢主資料檔案(通過另一份索引)Bloom Filter推薦作為避免重複訪問的主要機制。同樣的,Differential File也不保證Differential File一定是存在於記憶體中的。只是在3.4節裡提到,在Differential Filedump,以及後面被合併到主資料檔案時,可以將一個”differential-differential”檔案存於記憶體以允許線上的重組織。但是沒有對這種方式進行更多分析。它有些類似於LSM-tree中在C1C進行merge的同時,在記憶體中維護一個C0元件的策略,但是論文裡的描述看起來假設插入速率相對低些,在3.2節的例子中,它假設一個10,000,000條記錄的檔案每小時有100個變更。它沒有建議將”differential-differential”檔案一直存於記憶體,也沒有提到針對插入操作所能節省的IO

 

Selective Defered Text Index Updates

 

DadumLumPraedelSchlageter[7]提出的檔案索引維護方法也是設計用於提高系統索引更新效能的,通過延遲實際的磁碟寫入。索引更新會被快取在記憶體中,直到產生查詢衝突或者後臺任務觸發時才會被強制寫入。首先這是一個文字系統,這裡的衝突將會發生在文件關聯的關鍵字正在進行的更新操作以及與被修改的關鍵字相關聯的查詢操作之間。更新之後,查詢將會執行在磁碟索引上。因此與LSM-tree不同,記憶體快取並不是索引的一部分。這種延遲策略,允許進行批量的更新。但是這種更新模式依然類似於Continuum Structure

6. Conclusions and Suggested Extensions

B-tree,由於它最常用的目錄節點是快取在記憶體中的,實際上是一種混合資料結構,它使用廉價的磁碟儲存裝置來儲存主要資料,而對於那些訪問最多的資料則使用昂貴的記憶體提供訪問能力。LSM-tree將這種結構擴充套件到了多個層次,同時引入了執行multi-page磁碟讀取的merge IO的優勢。

 

6.1,是對圖3.1的一個擴充套件,它繪出了對於通過B-樹以及兩元件LSM-tree的兩種資料訪問模式中,Mbytes訪問開銷” Mbytes訪問頻率之間的關係。在比較低的資料訪問頻率下,”cold”資料比較適合放到磁碟儲存中,以典型的開銷來看,在0.04IO//Mbytes的情況下(”freezing point”),磁碟訪問開銷是$1/MByte”freezing point”之後就是”warm”資料區域,此時磁碟磁臂會成為資料訪問的限制因素,同時磁碟儲存空間處於未完全利用狀態;以例3.3來說,1 page IO/s/Mbyte的開銷是$25/Mbyte。最後,當資料訪問頻率高到B-tree訪問資料都應該快取到記憶體中時,就是”hot”資料了;由於記憶體開銷是$100/MByte,這樣訪問開銷就是$100/MByte,同時這也意味著4 IO/s/Mbyte的訪問頻率,也就是”boiling point”

The Log-Structured Merge-Tree(譯):下 - 星星 - 銀河裡的星星
B-樹的快取機制的效果是在Hot資料區域隨著訪問頻率的增加曲線依然很平坦,這樣當曲線越過Warm資料的上升階段後即使訪問頻率變得再高也不會導致更高的開銷。稍微思考一下,可知LSM-tree可以降低那些可merge的操作的訪問開銷,比如插入和刪除,同時對於Cold資料會更明顯。此外,很多需要全記憶體B-樹來解決的訪問場景,可以通過大部分駐留在磁碟上的LSM-tree就可以實現。在這些場景下,由於LSM-tree批量處理的影響,以邏輯訪問頻率(inserts/)來看資料是hot的,但是如果以物理磁碟的訪問頻率來衡量的話僅僅是warm的。這也是那些具有大量可merge操作的應用的一個極大的優勢。

6.1 LSM-tree應用的擴充套件

很明顯,LSM-tree記錄可以直接包含記錄內容,而不是通過RID指向儲存在磁碟上的記錄。這就意味著記錄本身可以根據它們的keyvalue進行聚集。這樣做的開銷在於更大的記錄大小,以及帶來的每秒插入速率R(以位元組為單位)的增長,也會因此影響到遊標移動以及總的IO頻率H。然而,正如我們在例3.3所看到的,一個三元件LSM-tree能夠以磁碟儲存空間的開銷提供儲存記錄和索引的需求,同時這裡所有的磁碟空間是以一種非聚簇的模式對行進行儲存的。

 

聚簇的優勢會對效能具有重要的影響。比如,考慮Escrow transactional method[20],由於長生命期更新的非阻塞屬性使得它可以很好地支援工作流管理。在Escrow method中,一個長生命期事務會產生大量的針對Escrow欄位的增量更新。我們需要儲存針對這些Escrow quantities的日誌,可以考慮使用兩種型別的聚簇索引:事務ID(TID),和發生Escrow quantities的欄位的欄位ID(FID)。在一段時間內,針對一個TID可能就會有20多條Escrow日誌,同時根據TID進行聚集在事務進行提交或abort時會顯得更為重要,這些都決定了這些日誌所應採取的結構。在commit時,發生在欄位上的quantities將會被持久化,因此日誌可以簡單地被丟棄,但是在abort發生時,我們希望可以根據日誌裡的FID返回針對該fieldquantity。同時對速率也有一定的要求。在處理一個abort時,被abort的事務的日誌需要能夠被訪問(通過TID進行聚簇是一個很大的優勢),同時對應FID的欄位需要被修正。但是,如果這個欄位不在記憶體中,那就需要讀取包含了根據FID進行聚集的對應日誌的記錄。之後當Escrow欄位被讀入到記憶體後,我們就可以嘗試訪問根據FID聚集的包含了可能需要的更新的所有日誌;這就又需要大量的日誌訪問,因此將這些日誌在LSM-tree中進行聚集將會節省很多開銷。使用LSM-tree來對Escrow日誌首先根據TID,然後根據FID進行聚集,在相關聯的欄位不在記憶體時,將會節省大量的IO。這種策略是在[20]中的”extended field”的一個改進。

 

另一個針對LSM-tree演算法的可能修改是在2.2節所提到的,保留一些最近的記錄在元件Ci中,而不是將它們全部移入到Ci+1中。根據這個想法可以產生更多的改進。比如在遊標迴圈移動過程中,可以生成一個基於時間-key的索引。通過對基於時間-key的索引進行一些控制,Rolling merge過程可以用來為新版本的插入操作提供很高的效率,同時多元件結構意味著可以將最後一個元件改成一個write-once儲存裝置。這種策略會在未來深入研究,同時它已做為一篇會議論文的主題。

 

關於未來的研究思路還有如下的一些:

(1)   對定理3.1中的成本分析方法以及例3.3進行擴充套件,使得它們可以適用於查詢操作必須和merge過程進行IO平衡的情況下。由於磁碟還有其他的額外負載,那麼將所有的磁碟能力都用於rolling merge過程就是不現實的,因此需要針對這種情況進行優化。磁碟能力的一部分必須要分給查詢操作。其他的一些擴充套件成本分析的方式比如允許刪除優先於向元件Ck的遷移,同時考慮在(Ci-1,Ci)merge中的內元件Ci-1的最近的記錄比例。

(2)   很明顯我們可以停下CPU的其他工作讓它專門維護LSM-tree,這樣CPU就不需要負責產生日誌記錄。我們只需要將日誌工作交給其他CPU,然後與它通訊檢視完成狀況。在共享記憶體的情況下,這幾乎不會增加額外的開銷。這種分散式工作方式的設計需要經過仔細地思考。

致謝

感謝Jim GrayDave Lomet的幫助,他們兩位閱讀了該論文的早期版本,並提出了寶貴的改進建議。此外,這篇文章的審稿人也提出很多有價值的建議。

參考文獻

[1] Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman, "The Design and Analysis of

Computer Algorithms", Addison-Wesley.

[2] Anon et al., "A Measure of Transaction Processing Power", Readings in Database Systems,edited by Michael Stonebraker, pp 300-312, Morgan Kaufmann, 1988.

[3] R. Bayer and M Schkolnick, "Concurrency of Operations on B-Trees", Readings in Database Systems, edited by Michael Stonebraker, pp 129-139, Morgan Kaufmann 1988.

[4] P. A. Bernstein, V. Hadzilacos, and N. Goodman, "Concurrency Control and Recovery in Database Systems", Addison-Wesley, 1987.

[5] D. Comer, "The Ubiquitous B-tree", Comput. Surv. 11, (1979), pp 121-137.

[6] George Copeland, Tom Keller, and Marc Smith, "Database Buffer and Disk Configuring and the Battle of the Bottlenecks", Proc. 4th International Workshop on High Performance Transaction Systems, September 1991.

[7] P. Dadam, V. Lum, U. Praedel, G. Shlageter, "Selective Deferred Index Maintenance &

Concurrency Control in Integrated Information Systems," Proceedings of the Eleventh

International VLDB Conference, August 1985, pp. 142-150.

[8] Dean S. Daniels, Alfred Z. Spector and Dean S. Thompson, "Distributed Logging for

Transaction Processing", ACM SIGMOD Transactions, 1987, pp. 82-96.

[9] R. Fagin, J. Nievergelt, N. Pippenger and H.R. Strong, Extendible Hashing — A Fast Access Method for Dynamic Files, ACM Trans. on Database Systems, V 4, N 3 (1979), pp 315-344

[10] H. Garcia-Molina, D. Gawlick, J. Klein, K. Kleissner and K. Salem, "Coordinating Multi-Transactional Activities", Princeton University Report, CS-TR-247-90, February 1990.

[11] Hector Garcia-Molina and Kenneth Salem, "Sagas", ACM SIGMOD Transactions, May 1987,pp. 249-259.

[12] Hector Garcia-Molina, "Modelling Long-Running Activities as Nested Sagas", IEEE Data Engineering, v 14, No 1 (March 1991), pp. 14-18.

[13] Jim Gray and Franco Putzolu, "The Five Minute Rule for Trading Memory for Disk

Accesses and The 10 Byte Rule for Trading Memory for CPU Time", Proceedings of the 1987 ACM SIGMOD Conference, pp 395-398.-32-

[14] Jim Gray and Andreas Reuter, "Transaction Processing, Concepts and Techniques",

Morgan Kaufmann 1992.

[15] Curtis P. Kolovson and Michael Stonebraker, "Indexing Techniques for Historical

Databases", Proceedings of the 1989 IEEE Data Engineering Conference, pp 138-147.

[16] Lomet, D.B.: A Simple Bounded Disorder File Organization with Good Performance, ACM Trans. on Database Systems, V 13, N 4 (1988), pp 525-551

[17] David Lomet and Betty Salzberg, "Access Methods for Multiversion Data", Proceedings of the 1989 ACM SIGMOD Conference, pp 315-323.

[18] David Lomet and Betty Salzberg, "The Performance of a Multiversion Access Method",Proceedings of the 1990 ACM SIGMOD Conference, pp 353-363.

[19] Patrick O'Neil, Edward Cheng, Dieter Gawlick, and Elizabeth O'Neil, "The Log-Structured Merge-Tree (LSM-tree)", UMass/Boston Math & CS Dept Technical Report, 91-6, November,1991.

[20] Patrick E. O'Neil, "The Escrow Transactional Method", TODS, v 11, No 4 (December

1986), pp. 405-430.

[21] Patrick E. O'Neil, "The SB-tree: An index-sequential structure for high-performance

sequential access", Acta Informatica 29, 241-265 (1992).

[22] Patrick O'Neil and Gerhard Weikum, "A Log-Structured History Data Access Method

(LHAM)," Presented at the Fifth International Workshop on High-Performance Transaction

Systems, September 1993.

[23] Mendel Rosenblum and John K. Ousterhout, "The Design and Implementation of a Log Structured File System", ACM Trans. on Comp. Sys., v 10, no 1 (February 1992), pp 26-52.

[24] A. Reuter, "Contracts: A Means for Controlling System Activities Beyond Transactional Boundaries", Proc. 3rd International Workshop on High Performance Transaction Systems,September 1989.

[25] Dennis G. Severance and Guy M. Lohman, "Differential Files: Their Application to the

Maintenance of Large Databases", ACM Trans. on Database Systems, V 1, N 3 (Sept. 1976), pp256-267.

[26] Transaction Processing Performance Council (TPC), "TPC BENCHMARK A Standard Specification", The Performance Handbook: for Database and Transaction Processing Systems,Morgan Kauffman 1991.

[27] Helmut W?chter, "ConTracts: A Means for Improving Reliability in Distributed

Computing", IEEE Spring CompCon 91.

[28] Gerhard Weikum, "Principles and Realization Strategies for Multilevel Transaction

Management", ACM Trans. on Database Systems, V 16, N 1 (March 1991), pp 132-180.

[29] Wodnicki, J.M. and Kurtz, S.C.: GPD Performance Evaluation Lab Database 2 Version 2 Utility Analysis, IBM Document Number GG09-1031-0, September 28, 1989.


相關文章