LSM樹(Log-Structured Merge Tree)存儲引擎淺析

其實每一種數據庫,它都是一種抽象的數據結構的具體實現。數據庫

隨着rocksDB(facebook的),levelDB(google的),以及咱們熟知的hbase,他們都是使用的LSM樹結構的數據庫。緩存

它的核心思路其實很是簡單,就是假定內存足夠大,所以不須要每次有數據更新就必須將數據寫入到磁盤中,而能夠先將最新的數據駐留在內存中,等到積累到最後多以後,再使用歸併排序的方式將內存內的數據合併追加到磁盤隊尾(由於全部待排序的樹都是有序的,能夠經過合併排序的方式快速合併到一塊兒)。下圖是最簡單的二層LSM Tree.數據結構

圖來自lsm論文性能

lsm tree,理論上,能夠是內存中樹的一部分和磁盤中第一層樹作merge,對於磁盤中的樹直接作update操做有可能會破壞物理block的連續性,可是實際應用中,通常lsm有多層,當磁盤中的小樹合併成一個大樹的時候,能夠從新排好順序,使得block連續,優化讀性能。優化

通常數據庫的存儲必定要保持有序,有序是一個很是重要的概念(固然hash結構的除外,hash不支持順序掃描,對應的存儲系統爲key-value存儲系統。對於key-value的插入以及查詢,哈希表的複雜度都是O(1),明顯比樹的操做O(n)快,若是不須要有序的遍歷數據,哈希表就是your Mr.Right ).google

LSM樹相比於B+樹(大量的葉節點操做,不只支持單條記錄的增、刪、讀、改操做,還支持順序掃描(B+樹的葉子節點之間的指針)對B樹的寫入過程是一次原位寫入的過程,主要分爲兩個部分,首先是查找到對應的塊的位置,而後將新數據寫入到剛纔查找到的數據塊中,而後再查找到塊所對應的磁盤物理位置,將數據寫入去。固然,在內存比較充足的時候,由於B樹的一部分能夠被緩存在內存中,因此查找塊的過程有必定機率能夠在內存內完成,不過爲了表述清晰,咱們就假定內存很小,只夠存一個B樹塊大小的數據吧。能夠看到,在上面的模式中,須要兩次隨機尋道(一次查找,一次原位寫),纔可以完成一次數據的寫入,代價仍是很高的。 ), 弄了不少個小的有序結構,好比每m個數據,在內存裏排序一次,下面100個數據,再排序一次……這樣依次作下去,我就能夠得到N/m個有序的小的有序結構。 在查詢的時候,由於不知道這個數據究竟是在哪裏,因此就從最新的一個小的有序結構裏作二分查找,找獲得就返回,找不到就繼續找下一個小有序結構,一直到找到爲止。 很容易能夠看出,這樣的模式,讀取的時間複雜度是(N/m)*log2N 。讀取效率是會降低的。spa

LSM樹原理把一棵大樹拆分紅N棵小樹,它首先寫入內存中,隨着小樹愈來愈大,內存中的小樹會flush到磁盤中,磁盤中的樹按期能夠作merge操做,合併成一棵大樹,以優化讀性能。指針

總結爲,LSM樹並非像B+樹單次在磁盤尋址,根據索引來進行寫入。而是大量堆集內存,達到必定閾值後,寫入磁盤,由於是批量處理,磁盤IO對其性能影響很小,對寫操做的性能大大提高。而後再磁盤內再進行合併(Merge)操做,再來提高讀性能,可見,對於即時讀取的性能不高,不可能寫進去立刻就讀出來,而是要通過一個Merge的過程。blog

相關文章
相關標籤/搜索