論文筆記 [FAST '16] WiscKey, Separating Keys from Values in SSD-conscious Storage
LSM-Tree的優勢在於借鑑LFS的思想,將大塊的記憶體連續的寫出到磁碟,減少磁碟seek的時間。同時輸出的格式又是連續的,查詢的速度也比較快。但是LSM-Tree的結構,也帶來了寫放大和讀放大的問題。這些影響在hdd上是值得的,但是在ssd上並不友好。WiscKey提出了一種面向ssd的,將key和value分開儲存的方法。
Write and Read Amplification
寫放大主要在於compaction的,每次兩層之間做compact時,都需要將多個sstable讀出做排序(讀放大),再寫到磁碟。而讀放大方面,LSM-Tree需要查詢多個數據結構,memtable->imutable->level files,假設不存在這個key的,便要把每一層做二分查詢搜一遍。特別是第0層,有overlap,需要每個檔案都看,雖然有bloom filter,但也影響效率。當value比較大的時候,問題就很明顯了,compaction時sstable的讀入和寫出,都是將key和value一起讀一起寫的,當value變長時,效率會很低。這些放大的影響在hdd,來換取磁碟seek的消耗還是值得,但是在SSD上就不一樣了,SSD隨機讀寫要快的多,並且有並行隨機讀取的特性可以利用。
WiscKey
key idea就是將key和value分開儲存,LSM-Tree裡只存key加一個value地址的偏移量,value放到另一個log檔案中。之所以可以做是因為,compaction的時候,其實並不需要value的參與,需要排序的只有key而已。idea很簡單,但是設計細節還是很複雜。有如下幾個問題需要解決。
- 因為key和value分開儲存,原先read的時候key和value是一起讀上的,現在多了一次seek。
- value的log檔案怎麼樣做垃圾回收?
- key和value分開在兩個地方寫,怎麼保證一致性。
Parallel Range Query
WiscKey很好的利用了SSD的特性,當key和value分開儲存讀取和寫入時,可以在後臺開啟多個執行緒並行讀取value log,但是這裡有個不足,是需要value足夠大,根據實驗資料當value大於4KB時,WiscKey的讀效能才能展現出來。
Garbage Collection
刪除key的時候,只是在LSM-Tree刪除,並不會涉及到value log,所以需要定期的清除無效的value。這裡比較有趣的是,為了方便做垃圾回事和一致性,value log,存的不僅是value,還有key。如下圖
垃圾回收的步驟如下
- 從tail開始資料
- 檢測key是否被刪除,或者修改了。(查詢LSM-Tree)
- 將依然有效的資料順序新增到head
- free 直接的space
這個垃圾回收工作不需要實時做,可以離線,效率還是很高的。
Crash Consistency
WiscKey無論是key丟失,還是value丟失都很好處理。
- 若是key丟失了,value還在,就和key被刪除的情況一樣。
- 若是key在,value丟失。因為value log也存了key,只要比較一下key是否相同即可,反之則刪除key。
還有一步可以優化的則是,可以去掉原來的WAL, 因為value log裡存了所有可以用來recovery的資訊。
Conclusion
WiscKey這種key與value分離的設計有如下優點。
- 減少寫放大和讀放大,compaction時只涉及到key,顯著減少資料量
- LSM-Tree的層高和sstable的數量會明顯減少。樹變小還可以更好的利用cache
但也有不足
- 對小value不友好
Reference
[1] WiscKey: Separating Keys from Values in SSD-conscious Storage. FAST ‘16