MongoDB 3.0新增特性一覽

chenfeng發表於2016-04-20
外掛式儲存引擎API

MongoDB 3.0引入了外掛式儲存引擎API,為第三方的儲存引擎廠商加入MongoDB提供了方便,這一變化無疑參考了MySQL的設計理念。
目前除了早期的MMAP儲存引擎外,WiredTiger和RocksDB均已完成了對MongoDB的支援,前者更是在被MongoDB公司收購後更是直接引入
到了MongoDB 3.0版本中。外掛式儲存引擎API的引入為MongoDB豐富自己武器庫以處理更多不同型別的業務提供了無限可能,記憶體儲存
引擎、事務儲存引擎甚至Hadoop在未來都有可能接入進來。 


WiredTiger儲存引擎

如果說外掛式儲存引擎API為MongoDB 3.0打造了一個武器庫,那麼WiredTiger絕對是武器庫中第一枚也是最重要的一枚重磅炸彈。
因為MMAP儲存引擎自身的天然缺陷(耗費磁碟空間和記憶體空間且難以清理,庫級別鎖),MongoDB為資料庫運維人員帶來了極大痛苦,
甚至一部分人已經開始轉向TokuMX,儘管後者目前也不甚穩定。意識到這一問題的MongoDB,做出了有錢任性的決定,直接收購儲存
引擎廠商WiredTiger,將WiredTiger儲存引擎整合進3.0版本(僅在64位版本中提供)。那麼這款走到聚光燈下的儲存引擎究竟具備哪些值得期待的特性呢?


1、文件級別併發控制


WiredTiger透過MVCC實現文件級別的併發控制,即文件級別鎖。這就允許多個客戶端請求同時更新一個集合記憶體的多個文件,再也不
需要在排隊等待庫級別的寫鎖。這在提升資料庫讀寫效能的同時,大大提高了系統的併發處理能力。關於這一點的效果從監控工具
mongostat就可以直接體現出來,舊版本的監控指標會有locked db這一項(該項指標過高是mongo使用人員的一大痛點啊),而新版的mongostat已經看不到了。


MongoDB 2.4.12版本

$ /home/mongodb/mongodb-linux-x86_64-2.4.12/bin/mongostat –port 55060 
insert query update delete getmore command flushes mapped vsize res faults locked db idx miss % qr|qw ar|aw netIn netOut conn time 
*0 *0 *0 *0 0 1|0 0 18g 18.3g 16.1g 0 ycsb:0.0% 0 0|0 0|0 62b 2k 1 13:04:01 
*0 *0 *0 *0 0 1|0 0 18g 18.3g 16.1g 0 ycsb:0.0% 0 0|0 0|0 62b 2k 1 13:04:02 
*0 *0 *0 *0 0 1|0 0 18g 18.3g 16.1g 0 ycsb:0.0% 0 0|0 0|0 62b 2k 1 13:04:03 
MongoDB 3.0 rc8版本


$ /home/mongodb/mongodb-linux-x86_64-3.0.0-rc8/bin/mongostat –port 55050 
insert query update delete getmore command % dirty % used flushes vsize res qr|qw ar|aw netIn netOut conn time 
*0 *0 *0 *0 0 1|0 0.0 42.2 0 30.6G 30.4G 0|0 0|0 79b 16k 1 13:02:38 
*0 *0 *0 *0 0 1|0 0.0 42.2 0 30.6G 30.4G 0|0 0|0 79b 16k 1 13:02:39 
*0 *0 *0 *0 0 1|0 0.0 42.2 0 30.6G 30.4G 0|0 0|0 79b 16k 1 13:02:40 



2、磁碟資料壓縮




WiredTiger支援對所有集合和索引進行Block壓縮和字首壓縮(如果資料庫啟用了journal,journal檔案一樣會壓縮),已支援的壓縮選項包括:
不壓縮、Snappy壓縮和Zlib壓縮。這為廣大Mongo使用者們帶來了又一福音,因為很多Mongo資料庫都是因為MMAP儲存引擎消耗了過多的磁碟空間
而不得已進行擴容。其中Snappy壓縮為資料庫的預設壓縮方式,使用者可以根據業務需求選擇適合的壓縮方式。理論上來說,Snappy壓縮速度快,
壓縮率OK,而Zlib壓縮率高,CPU消耗多且速度稍慢。當然,只要選擇使用壓縮,Mongo肯定會佔用更多的CPU使用率,但是考慮到Mongo本身並不
是十分耗CPU,所以啟用壓縮完全是值得的。



此外,WiredTiger儲存方式上也有很大改進。舊版本Mongo在資料庫級別分配檔案,資料庫中的所有集合和索引都混合儲存在資料庫檔案中,所以
即使刪掉了某個集合或者索引,佔用的磁碟空間也很難及時自動回收。WiredTiger在集合和索引級別分配檔案,資料庫中的所有集合和索引均儲存
在單獨的檔案中,集合或者索引刪除後,對應的儲存檔案隨即刪除。當然,因為儲存方式不同,低版本的資料庫無法直接升級到WiredTiger儲存引擎,
只能透過匯出匯入資料的方式來實現。



MongoDB 2.4.12版本

[mongodb@mongo-data-emergency-001.m6.momo.com mongodb_2_4_12]$ ll 
drwxrwxr-x 3 mongodb mongodb 4096 2月 25 19:03 local 
-rwxrwxr-x 1 mongodb mongodb 6 2月 25 19:04 mongod.lock 
drwxrwxr-x 2 mongodb mongodb 4096 2月 27 18:30 _tmp 
drwxrwxr-x 3 mongodb mongodb 4096 2月 27 18:39 ycsb 
[mongodb@mongo-data-emergency-001.m6.momo.com mongodb_2_4_12]$ ll ycsb/ 
drwxrwxr-x 2 mongodb mongodb 4096 2月 27 18:39 _tmp 
-rw——- 1 mongodb mongodb 67108864 2月 27 18:57 ycsb.0 
-rw——- 1 mongodb mongodb 134217728 2月 27 18:57 ycsb.1 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.10 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.11 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.12 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:39 ycsb.13 
-rw——- 1 mongodb mongodb 268435456 2月 27 18:57 ycsb.2 
-rw——- 1 mongodb mongodb 536870912 2月 27 18:57 ycsb.3 
-rw——- 1 mongodb mongodb 1073741824 2月 27 18:57 ycsb.4 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.5 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.6 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.7 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.8 
-rw——- 1 mongodb mongodb 2146435072 2月 27 18:57 ycsb.9 
-rw——- 1 mongodb mongodb 16777216 2月 27 18:40 ycsb.ns 

Mongo 3.0 rc8版本

[mongodb@mongo-data-emergency-001.m6.momo.com mongodb_3_0_0]$ ll 
drwxrwxr-x 2 mongodb mongodb 4096 2月 28 18:32 local 
-rw-rw-r– 1 mongodb mongodb 36864 3月 21 13:41 _mdb_catalog.wt 
-rwxrwxr-x 1 mongodb mongodb 6 2月 28 18:32 mongod.lock 
-rw-rw-r– 1 mongodb mongodb 36864 3月 21 13:42 sizeStorer.wt 
-rw-rw-r– 1 mongodb mongodb 95 2月 28 18:32 storage.bson 
-rw-rw-r– 1 mongodb mongodb 49 2月 28 18:32 WiredTiger 
-rw-rw-r– 1 mongodb mongodb 433 2月 28 18:32 WiredTiger.basecfg 
-rw-rw-r– 1 mongodb mongodb 21 2月 28 18:32 WiredTiger.lock 
-rw-rw-r– 1 mongodb mongodb 921 3月 21 13:41 WiredTiger.turtle 
-rw-rw-r– 1 mongodb mongodb 53248 3月 21 13:41 WiredTiger.wt 
drwxrwxr-x 2 mongodb mongodb 4096 3月 21 13:41 ycsb 
[mongodb@mongo-data-emergency-001.m6.momo.com mongodb_3_0_0]$ ll ycsb/ 
-rw-rw-r– 1 mongodb mongodb 19314257920 2月 28 19:16 collection-4–1318477584648278106.wt 
-rw-rw-r– 1 mongodb mongodb 602112 3月 21 13:40 collection-6–1318477584648278106.wt 
-rw-rw-r– 1 mongodb mongodb 262598656 2月 28 18:53 index-5–1318477584648278106.wt 
-rw-rw-r– 1 mongodb mongodb 827392 3月 21 13:40 index-7–1318477584648278106.wt 
-rw-rw-r– 1 mongodb mongodb 1085440 3月 21 13:41 index-8–1318477584648278106.wt 


3、可配置記憶體使用上限


WiredTiger支援記憶體使用容量配置,使用者透過storage.wiredTiger.engineConfig.cacheSizeGB引數即可控制MongoDB所能使用的最大記憶體,該引數
預設值為實體記憶體大小的一半。這也為廣大Mongo使用者們帶來了又一福音,MMAP儲存引擎消耗記憶體是出了名的,只要資料量夠大,簡直就是有多少用多少。


MMAPv1儲存引擎提升


MongoDB 3.0出了引入WiredTiger外,對於原有的儲存引擎MMAP也進行了一定的完善,該儲存引擎依然是3.0版的預設儲存引擎。遺憾的是改進後的MMAP
儲存引擎依舊在資料庫級別分配檔案,資料庫中的所有集合和索引都混合儲存在資料庫檔案中,所以磁碟空間無法及時自動回收的問題如故。


1、鎖粒度由庫級別鎖提升為集合級別鎖

這在一定程度上也能夠提升資料庫的併發處理能力。



2、文件空間分配方式改變


在MMAP儲存引擎中,文件按照寫入順序排列儲存。如果文件更新後長度變長且原有儲存位置後面沒有足夠的空間放下增長部分的資料,那麼文件就要移動到檔案
中的其他位置。這種因更新導致的文件位置移動會嚴重降低寫效能,因為一旦文件發生移動,集合中的所有索引都要同步修改文件新的儲存位置。


MMAP儲存引擎為了減少這種情況的發生提供了兩種文件空間分配方式:基於paddingFactor(填充因子)的自適應分配方式和基於usePowerOf2Sizes的預分配方式,
其中前者為預設方式。第一種方式會基於每個集合中文件更新歷史計算文件更新的平均增長長度,然後在新文件插入或舊文件移動時填充一部分空間,如當前集合
paddingFactor的值為1.5,那麼一個大小為200位元組的文件插入時就會自動在文件後填充100個位元組的空間。第二種方式則不考慮更新歷史,直接為文件分配2的N次方
大小的儲存空間,如一個大小同樣為200位元組的文件插入時直接分配256個位元組的空間。


MongoDB 3.0版本中的MMAPv1拋棄了基於paddingFactor的自適應分配方式,因為這種方式看起來很智慧,但是因為一個集合中的文件的大小不一,所以經過填充後的
空間大小也不一樣。如果集合上的更新操作很多,那麼因為記錄移動後導致的空閒空間會因為大小不一而難以重用。目前基於usePowerOf2Sizes的預分配方式成為預設
的文件空間分配方式,這種分配方式因為分配和回收的空間大小都是2的N次方(當大小超過2MB時則變為2MB的倍數增長),因此更容易維護和利用。如果某個集合上只
有insert或者in-place update,那麼使用者可以透過為該集合設定noPadding標誌位,關閉空間預分配。


複製集改進


1、複製整合員增長


MongoDB 3.0的複製整合員的最大個數由之前的12個增長為50個,但能夠投票的最大成員個數依然為7個,而相應的getLastError中的 w: “majority” 項也僅代表投票節點
的大多數。


2、Primary節點StepDown處理方式變化

在複製集中透過replSetStepDown命令可以使得當前的Primary節點退位,重新選舉新的Primay節點。MongoDB 3.0在StepDown的處理方式上做了如下修改:
1)在Primary退位之前,會首先中斷某些耗時較長的使用者操作如建立索引、寫操作、Mapreduce任務等;2)為了防止資料回滾,Primary節點在退位之前會等待一個可被選舉
的Secondary節點同步到最新資料,而舊版本中Primary節點只要有Secondary節點的資料同步到10秒以內就退位;3)同時replSetStepDown命令新增了一個secondaryCatchUpPeriodSecs引數,
使用者可以指定Primary節點等待有Secondary節點的資料同步到該引數指定的秒數內就退位。


分片叢集改進

1、新增工具函式 sh.removeTagRange()


舊版本中只有sh.addTagRange(),如果要刪除tagRange只能手工到config.tags集合中刪除。


2、提供更可預測的Read Preference處理


新版本中mongos例項在執行讀操作時不再將連線固定在複製整合員上,而是對每個讀操作都會重新評估Read Preference。這樣當Read Preference修改時,其行為更容易預測。


3、為chunk遷移提供writeConcern設定

新版本針對均衡器為moveChunk和cleanupOrphaned這兩個涉及到chunk遷移的命令提供了writeConcern引數。

4、增加均衡器狀態顯示


新版本中透過sh.status()可以看到均衡器的狀態資訊。


其他改動


1、最佳化explan函式

新版本explain函式可以支援count,find,group,aggregate,update,remove等操作的查詢計劃顯示,結果更全面更精細。




2、重寫mongodb工具

新版本所有mongodb自帶工具均使用Go語言重寫,特別是在mongodump和mongorestore新增了並行機制,這樣可以大大加快資料的匯出和匯入。




3、日誌輸出控制

新版本中將日誌分為不同的模組,其中包括ACCESS、COMMAND、CONTROL、GEO、INDEX、NETWORK、QUERY、REPL、SHARDING、STORAGE、JOURNAL和WRITE等。使用者可以動態
調整每個模組的日誌級別,這無疑更有利於系統問題診斷。



4、 索引構建最佳化

後臺索引建立過程中,不能進行刪庫刪表刪索引操作,且後臺索引建立過程不會因此自動中斷。另外,使用createIndexes命令可以同時建立多個索引,並且只掃描一遍
資料,提升了建索引的效率。




總結
以上僅列出了MongoDB 3.0的一些主要特性和修改,如果希望瞭解更多可以檢視MongoDB 3.0的Release-Notes。總體來看,MongoDB 3.0提供了較多令人驚喜的新特性,
也使人們更加看好其未來的發展。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2084564/,如需轉載,請註明出處,否則將追究法律責任。

相關文章