標籤:分布式儲存 儲存系統 讀書筆記 lsm
----《大規模分布式儲存系統:原理解析與架構實戰》讀書筆記
之前研究了Bitcask儲存模型,今天來看看LSM儲存模型,兩者雖然同屬於基於鍵值的日誌型儲存模型。但是Bitcask使用雜湊表建立索引,而LSM使用跳躍表建立索引。這一差別導致了兩個儲存系統的構造出現明顯的分化。為此,我還先去搗騰了一番跳躍表的實現.今天算是進入了正題。
LSM的結構
LSM的基本思想是將修改的資料儲存在記憶體,達到一定數量後在將修改的資料批量寫入磁碟,在寫入的過程中與之前已經存在的資料做合并。同B樹儲存模型一樣,LSM儲存模型也支援增、刪、讀、改以及順序掃描操作。LSM模型利用批量寫入解決了隨機寫入的問題,雖然犧牲了部分讀的效能,但是大大提高了寫的效能。
MemTable
LSM本身由MemTable,Immutable MemTable,SSTable等多個部分組成,其中MemTable在記憶體,用於記錄最近修改的資料,一般用跳躍表來組織。當MemTable達到一定大小後,將其凍結起來變成Immutable MemTable,然後開闢一個新的MemTable用來記錄新的記錄。而Immutable MemTable則等待轉存到磁碟。
Immutable MemTable
所謂Immutable MemTable,即是只能讀不能寫的記憶體表。記憶體部分已經有了MemTable,為什麼還要使用Immutable MemTable?個人認為其原因是為了不阻塞寫操作。因為轉存的過程中必然要保證記憶體表的記錄不變,否則如果新插入的記錄夾在兩條已經轉存到磁碟的記錄中間,處理上會很麻煩,轉存期間勢必要鎖住全表,這樣一來就會阻塞寫操作。所以不如將原有的MemTable變成唯讀Immutable MemTable,在開闢一個新的MemTable用於寫入,即簡單,又不影響寫操作。
SSTable
SSTable是本意是指有序的鍵值對集合( a set of sorted key-value pairs )。是一個簡單有用的集合,正如它的名字一樣,它儲存的就是一系列的鍵值對。當檔案較大的時候,還可以為其建立一個鍵-值的位置的索引,指明每個鍵在SSTable檔案中的位移距離。這樣可以加速在SSTable中的查詢。(當然這一點是可選的,同時讓我想去了Bitcask模型中hint檔案,通過記錄 鍵-值的位置 ,來加速索引構建)
使用MemTable和SSTable這兩個組件,可以構建一個最簡單的LSM儲存模型。這個模型與Bitcask模型相比,不存在啟動時間長的問題,但是這個模型的讀效能非常的差,因為一但在MemTable找不到相應的鍵,則需要在根據SSTable檔案產生的時間,從最近到較早在SSTable中尋找,如果都不存在的話,則會遍曆完所有的SSTable檔案。
如果SSTable檔案個數很多或者沒有建立SSTable的檔案內索引的話,讀效能則會大大下降。
除了在對SSTable內部建立索引外,還可以使用Bloom Fileter,提高Key不在SSTable的判定速度。同樣,定期合并舊的SSTable檔案,在減少儲存的空間的同時,也能提高讀取的速度。下面這幅圖很好的描述了在LSM的大部分結構和操作
LevelDB如何最佳化讀效能
Leveldb是一個輕量級的,快速的以儲存為目的的key-value儲存引擎。其使用的正是LSM儲存模型。我們可以看看LevelDB是如何來最佳化讀效能的。在LevelDB中,存在一種元資訊檔MANIFEST,用於記錄leveldb的元資訊,比如DB使用的Comparator名,以及各SSTable檔案的管理資訊:如Level層數、檔案名稱、最小key和最大key等等。相比而言,元資訊檔而SSTable檔案的數目成正比,一般來說不會太多,是可以載入記憶體的,因此Level可以通過查詢元資訊,從而判斷哪些檔案中存在我們需要的Key對應的記錄,減少SSTable檔案讀取次數。此外,LevelDB的合併作業Compaction是分層次進行的,每一層都有多個SSTable檔案,每次合并後除了Level0和記憶體的MemTable,Immutable MemTable中會有重複的鍵值外,LevelN(N>=1)的各層內部的SSTable檔案不會再有重複的鍵值。同時,如果在Level N 層讀到了資料,那麼就不需要再往後讀Level N+1,Level N+2等層的資料了.因為Level N層的資料總是比Level N+1等層的資料更“新鮮”。
實現一個簡單的LSM儲存模型
根據上面講述的原理,實現了一個簡單的LSM模型(https://github.com/Winnerhust/Code-of-Book/blob/master/Large-Scale-Distributed-Storage-System/lsm_tree.py)。這個模型也記憶體表為一個跳躍表,SSTable就是簡單的有序鍵值對集合,沒有SSTable內部使用索引,沒有使用Bloom過濾器。其實能就是將我之前的Bitcask模型進行了簡單的改造:
- 將原來的雜湊表換成了跳躍表;
- 原來讀取記錄完全依賴雜湊表,現在如果在跳躍表中沒有的話,就去讀取檔案SSTable檔案中的資料,根據檔案編號從大到小進行,編號越大,表示資料越新;
- 去掉了載入資料的功能(LSM不需要);
簡單起見,沒有完成對範圍掃描的支援,不過記憶體表和SSTable都是有序的,因此這個也不是很難。
參考:
詳解SSTable結構和LSMTree索引
歡迎光臨我的網站----蝴蝶忽然的部落格園----人既無名的專欄。
如果閱讀本文過程中有任何問題,請聯絡作者,轉載請註明出處!
LSM樹儲存模型