reids 的 RDB 和 AOF mysql
RDB,以某個時間點爲切面,將這個時候內存中的數據寫入到磁盤。redis
AOF ,將全部內存中的改動記錄在AOF日誌裏,要恢復的時候,依次按操做恢復。當AOF過大時,還會進行重寫,把重複的操做合併。sql
mongodb(相似於redis aof)
mongodb與MySQL不一樣,mysql的每一次更新操做都會直接寫入硬盤,可是mongo不會,作爲內存型數據庫,數據操做會先寫入內存,而後再會持久化到硬盤中去。
mongodb在啓動時,專門初始化一個線程不斷循環,用於在必定時間週期內來從defer隊列中獲取要持久化的數據並寫入到磁盤的journal(日誌)和mongofile(數據)處。mongodb
hbase
hbase採用的LSM思想(Log-Structured Merge-Tree)。數據庫
根節點和枝節點很簡單,分別記錄每一個葉子節點的最小值,並用一個指針指向葉子節點。性能
葉子節點裏每一個鍵值都指向真正的數據塊(如Oracle裏的RowID),每一個葉子節點都有前指針和後指針,這是爲了作範圍查詢時,葉子節點間能夠直接跳轉,從而避免再去回溯至枝和跟節點。線程
B+樹最大的性能問題是會產生大量的隨機IO,隨着新數據的插入,葉子節點會慢慢分裂,邏輯上連續的葉子節點在物理上每每不連續,甚至分離的很遠,但作範圍查詢時,會產生大量讀隨機IO。指針
對於大量的隨機寫也同樣,舉一個插入key跨度很大的例子,如7->1000->3->2000 ... 新插入的數據存儲在磁盤上相隔很遠,會產生大量的隨機寫IO.日誌
從上面能夠看出,低下的磁盤尋道速度嚴重影響性能(近些年來,磁盤尋道速度的發展幾乎處於停滯的狀態)。隊列
爲了克服B+樹的弱點,HBase引入了LSM樹的概念,即Log-Structured Merge-Trees。
爲了更好的說明LSM樹的原理,下面舉個比較極端的例子:
如今假設有1000個節點的隨機key,對於磁盤來講,確定是把這1000個節點順序寫入磁盤最快,可是這樣一來,讀就悲劇了,由於key在磁盤中徹底無序,每次讀取都要全掃描;
那麼,爲了讓讀性能儘可能高,數據在磁盤中必須得有序,這就是B+樹的原理,可是寫就悲劇了,由於會產生大量的隨機IO,磁盤尋道速度跟不上。
LSM樹本質上就是在讀寫之間取得平衡,和B+樹相比,它犧牲了部分讀性能,用來大幅提升寫性能。
它的原理是把一顆大樹拆分紅N棵小樹, 它首先寫入到內存中(內存沒有尋道速度的問題,隨機寫的性能獲得大幅提高),在內存中構建一顆有序小樹,隨着小樹愈來愈大,內存的小樹會flush到磁盤上。當讀時,因爲不知道數據在哪棵小樹上,所以必須遍歷全部的小樹,但在每顆小樹內部數據是有序的。因此LSM樹讀是比較慢的。
以上就是LSM樹最本質的原理,有了原理,再看具體的技術就很簡單了。
1)首先說說爲何要有WAL(Write Ahead Log),很簡單,由於數據是先寫到內存中,若是斷電,內存中的數據會丟失,所以爲了保護內存中的數據,須要在磁盤上先記錄logfile,當內存中的數據flush到磁盤上時,就能夠拋棄相應的Logfile。
2)什麼是memstore, storefile?很簡單,上面說過,LSM樹就是一堆小樹,在內存中的小樹即memstore,每次flush,內存中的memstore變成磁盤上一個新的storefile。
3)爲何會有compact?很簡單,隨着小樹愈來愈多,讀的性能會愈來愈差,所以須要在適當的時候,對磁盤中的小樹進行merge,多棵小樹變成一顆大樹。提升讀的性能。