摘要
在MongoDB 初識篇中談到過Mongo 與 Cassandra的差別,這邊再談談Mongo與Cassandra的存儲引擎差别
概括
存儲引擎:
類型 | 功能 | 應用 |
---|---|---|
hash | 增删改、随機讀、順序掃描 | Key-Value存儲系統 |
B-Tree | 關系型資料庫 | |
LSM | 分布式存儲系統,如cassandra、google LevelDB |
緩存管理
緩存管理的核心在于置換算法,置換算法常見的有FIFO(First In First Out),LRU(Least Recently Used)。關系型資料庫在LRU的基礎上,進行了改進,主要使用LIRS(Low Inter-reference Recency Set)
将緩存分為兩級,第一次采用LRU,最近被使用到的資料會進第一級,如果資料在較短時間内被通路了兩次或以上,則成為熱點資料,進入第二級。避免了進行全表掃描的時候,可能會将緩存中的大量熱點資料替換掉。
Log-Structured Merge Tree:結構化合并樹,核心思想就是不将資料立即從記憶體中寫入到磁盤,而是先儲存在記憶體中,積累了一定量後再刷到磁盤中
LSM VS B-Tree
LSM在B-Tree的基礎上為了擷取更好的寫性能而犧牲了部分的讀性能,同時利用其它的實作來彌補讀性能,比如boom-filter.
1.寫
B樹的寫入,是首先找到對應的塊位置,然後将新資料插入。随着寫入越來越多,為了維護B樹結構,節點得分裂。這樣插入資料的随機寫機率就會增大,性能會減弱。
LSM 則是在記憶體中形成小的排好序的樹,然後flush到磁盤的時候不斷的做merge.因為寫入都是記憶體寫,不寫磁盤,是以寫會很高效。
2.讀
B樹從根節點開始二分查詢直到葉子節點,每次讀取一個節點,如果對應的頁面不在記憶體中,則讀取磁盤,緩存資料。
LSM樹整個結構不是有序的,是以不知道資料在什麼地方,需要從每個小的有序結構中做二分查詢,找到了就傳回,找不到就繼續找下一個有序結構。是以說LSM犧牲了讀性能。但是LSM之是以能夠作為大規模資料存儲系統在于讀性能可以通過其他方式來提高,比如讀取性能更多的依賴于記憶體/緩存命中率而不是磁盤讀取。
Cassandra
Cassandra是一個寫性能優于讀性能的NoSql資料庫,寫性能好一個原因在于選擇了LSM存儲引擎。
Mongo
MMAPv1
Mongo 3.2以前預設使用MMAPv1存儲引擎,是基于B-Tree類型的。
邊界(padding)
MMAPv1 存儲引擎使用一個叫做”記錄配置設定”的過程來為document存儲配置設定磁盤空間。MongoDB與Cassandra不同的是,需要去更新原有的document。如果原有的document空間不足,則需要将這個document移動到新的位置,更新對應的index。這樣就會導緻一些不必要的更新,和資料碎片。
為了避免出現上述情況,就有了邊界的概念,就是為document預配置設定空間。但是這樣就有可能造成資源的浪費。mongo 按照64M,128M,256M…2G的2的冥次方遞增政策預配置設定,最大2G。在資料量小的情況下問題并不明顯,但是當達到2G時,磁盤占用量大的問題就出來了。
同樣這一點和關系型資料庫也不一樣,關系型資料庫對于長記錄資料會分開存儲。
鎖
MMAPv1使用collection級别的鎖,即一個collecion增,删,改一次隻能有一個。在并發操作時,就會造成等待。
WiredTiger
3.2及其以後的預設存儲引擎,同樣是基于B-Tree的。采用了lock-free,風險指針等并發技術,使得在多核機器上工作的更好。
鎖級别為document。并且引入了compression,減少了磁盤占用。
參考
https://docs.mongodb.com/manual/core/mmapv1/
http://weibo.com/ttarticle/p/show?id=2309403985460371265557