LSM-Tree--BigTable 的理論模型

轉載以下2篇文章

http://bofang.iteye.com/blog/1676698

http://www.cnblogs.com/raymondshiquan/archive/2011/06/04/2072630.html


LSM-tree主要目標是快速地建立索引。B-tree是建立索引的通用技術,但是,在大併發插入數據的情況下,B-tree需要大量的磁盤隨機IO,很顯然,大量的磁盤隨機IO會嚴重影響索引建立的速度。特別地,對於那些索引數據大的情況(例如,兩個列的聯合索引),插入速度是對性能影響的重要指標,而讀取相對來說就比較少。LSM-tree通過磁盤的順序寫,來達到最優的寫性能,因爲這會大大降低磁盤的尋道次數,一次磁盤IO可以寫入多個索引塊。

 

LSM-tree的主要思想是劃分不同等級的樹。以兩級樹爲例,可以想象一份索引數據由兩個樹組成,一棵樹存在於內存,一棵樹存在於磁盤。內存中的樹可以不一定是B-樹,可以是其他的樹,例如AVL樹。因爲數據大小是不同的,沒必要犧牲CPU來達到最小的樹高度。而存在於磁盤的樹是一棵B-樹。

 

 

數據首先會插入到內存中的樹。當內存中的樹中的數據超過一定閾值時,會進行合併操作。合併操作會從左至右遍歷內存中的樹的葉子節點與磁盤中的樹的葉子節點進行合併,當被合併的數據量達到磁盤的存儲頁的大小時,會將合併後的數據持久化到磁盤,同時更新父親節點對葉子節點的指針。

 

 

之前存在於磁盤的葉子節點被合併後,舊的數據並不會被刪除,這些數據會拷貝一份和內存中的數據一起順序寫到磁盤。這會操作一些空間的浪費,但是,LSM-tree提供了一些機制來回收這些空間。

 

磁盤中的樹的非葉子節點數據也被緩存在內存中。

 

數據查找會首先查找內存中樹,如果沒有查到結果,會轉而查找磁盤中的樹。

 

有一個很顯然的問題是,如果數據量過於龐大,磁盤中的樹相應地也會很大,導致的後果是合併的速度會變慢。一個解決方法是建立各個層次的樹,低層次的樹都比上一層次的樹數據集大。假設內存中的樹爲c0, 磁盤中的樹按照層次一次爲c1, c2, c3, ... ck-1, ck。合併的順序是(c0, c1), (c1, c2)...(ck-1, ck)。

 

爲什麼LSM-tree的插入很快

 

1. 首先,插入操作首先會作用於內存,並且,內存中的樹不會很大,這會很快。

2. 合併操作會順序寫入一個或多個磁盤頁,這比隨機寫快得多。



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



Google的BigTable架構在分佈式結構化存儲方面大名鼎鼎,其中的MergeDump模型在讀寫之間找到了一個較好的平衡點,很好的解決了web scale數據的讀寫問題。

MergeDump的理論基礎是LSM-Tree (Log-Structured Merge-Tree), 原文見:LSM Tree

下面先說一下LSM-Tree的基本思想,再記錄下讀文章的幾點感受。

LSM思想非常樸素,就是將對數據的更改hold在內存中,達到指定的threadhold後將該批更改批量寫入到磁盤,在批量寫入的過程中跟已經存在的數據做rolling merge。

拿update舉個例子:

比如有1000萬行數據,現在希望update table.a set addr='new addr' where pk = '833',

如果使用B-Tree類似的結構操作,就需要:

1. 找到該條記錄所在的page,

2. load page到內存(如果恰好該page已經在內存中,則省略該步)

3. 如果該page之前被修改過,則先flush page to disk

4. 修改數據

上面的動作平均來說有兩次disk I/O,

如果採用LSM-Tree類似結構,則:

1. 將需要修改的數據直接寫入內存

可見這裏是沒有disk I/O的。

當然,我們要說,這樣的話讀的時候就費勁了,需要merge disk上的數據和memory中的修改數據,這顯然降低了讀的性能。

確實如此,所以作者其中有個假設,就是寫入遠大於讀取的時候,LSM是個很好的選擇。我覺得更準確的描述應該是”優化了寫,沒有顯著降低讀“,因爲大部分時候我們都是要求讀最新的數據,而最新的數據很可能還在內存裏面,即使不在內存裏面,只要不是那些更新特別頻繁的數據,其I/O次數也是有限的。

所以LSM-Tree比較適合的應用場景是:insert數據量大,讀數據量和update數據量不高且讀一般針對最新數據。

文章讀下來有以下幾點感受:

1. 基本思想早就有了,作者給出了較好的表現形式。

2. Merge是page/block級別的,而不是BigTable中的文件級別的。這一點主要原因可能是BigTable在分佈式場景下做block級別很困那,而且GFS也不支持修改。

3. 其提出的比較標準比較有趣,將磁盤容量,轉速等結合起來給出一個以美元爲單位的cost標準,然後跟B-Tree結構的實現做了比較,結果當然是大大勝出。但是這裏我覺得作者有些比較是不合理的,比如LSM使用log而B-Tree沒有使用,這顯然對B-Tree不公,其實B-Tree如果使用log,寫入性能應該不比LSM差,順序讀取可能差一些。

4. 在Multi components 中,提出Ci/Ci+1的比例達到20的時候是最優的,這個數字意義不大,但是其中的分析方法對於Merge策略的選擇是個啓發。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章