本文主要介紹mongodb3.0的新特性,及具體由2.6 到3.0的升級過程。html
mongodb3.0的新特性:參照(http://dataunion.org/12868.html)
java
相似mysql 的思想。 目前除了早期的MMAP存儲引擎外,WiredTiger和 RocksDB 均已完成了對MongoDB的支持,前者更是在被MongoDB公司收購後更是直接引入到了MongoDB 3.0版本中。插件式存儲引擎API的引入爲MongoDB豐富本身武器庫以處理更多不一樣類型的業務提供了無限可能,內存存儲引擎、事務存儲引擎甚至Hadoop在將來都有可能接入進來。mysql
MMAP存儲引擎自身的自然缺陷(耗費磁盤空間和內存空間且難以清理,庫級別鎖)。git
1文檔級別併發控制: WiredTiger經過MVCC實現文檔級別的併發控制,即文檔級別鎖。這就容許多個客戶端請求同時更新一個集合內存的多個文檔,不再須要在排隊等待 庫級別的寫鎖。這在提高數據庫讀寫性能的同時,大大提升了系統的併發處理能力。關於這一點的效果從監控工具mongostat就能夠直接體現出來,舊版本 的監控指標會有locked db這一項(該項指標太高是mongo使用人員的一大痛點啊),而新版的mongostat已經看不到了。github
2磁盤數據壓縮: WiredTiger支持對全部集合和索引進行Block壓縮和前綴壓縮(若是數據庫啓用了journal,journal文件同樣會壓縮),已支持的壓 縮選項包括:不壓縮、Snappy壓縮和Zlib壓縮。這爲廣大Mongo使用者們帶來了又一福音,由於不少Mongo數據庫都是由於MMAP存儲引擎消 耗了過多的磁盤空間而不得已進行擴容。其中Snappy壓縮爲數據庫的默認壓縮方式,用戶能夠根據業務需求選擇適合的壓縮方式。理論上來講,Snappy 壓縮速度快,壓縮率OK,而Zlib壓縮率高,CPU消耗多且速度稍慢。固然,只要選擇使用壓縮,Mongo確定會佔用更多的CPU使用率,可是考慮到 Mongo自己並非十分耗CPU,因此啓用壓縮徹底是值得的。 此外,WiredTiger存儲方式上也有很大改進。舊版本Mongo在數據庫級別分配文件,數據庫中的全部集合和索引都混合存儲在數據庫文件中,因此即 使刪掉了某個集合或者索引,佔用的磁盤空間也很難及時自動回收。WiredTiger在集合和索引級別分配文件,數據庫中的全部集合和索引均存儲在單獨的 文件中,集合或者索引刪除後,對應的存儲文件隨即刪除。固然,由於存儲方式不一樣,低版本的數據庫沒法直接升級到WiredTiger存儲引擎,只能經過導 出導入數據的方式來實現。spring
MongoDB 3.0出了引入WiredTiger外,對於原有的存儲引擎MMAP也進行了必定的完善,該存儲引擎依然是3.0版的默認存儲引擎。遺憾的是改進後的 MMAP存儲引擎依舊在數據庫級別分配文件,數據庫中的全部集合和索引都混合存儲在數據庫文件中,因此磁盤空間沒法及時自動回收的問題如故。sql
一、鎖粒度由庫級別鎖提高爲集合級別鎖mongodb
這在必定程度上也可以提高數據庫的併發處理能力。shell
二、文檔空間分配方式改變數據庫
在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標誌位,關閉空間預分配。
下面介紹由2.6 升級到3.0 的過程。
升級過程
1搭建3.0 分片+副本 集羣模式
mongodb 集羣通常是shard(分片)+ replicateSet(副本集)+mongos(路由)+config(配置服務)
shard :分片顧名思義就是把本來的數據放在一堆,如今分開放。能夠分2堆 ,3 堆 ,n 堆,可是每堆之間的數據不能重複。
這樣作的好事天然是能夠把數據分別放到不一樣的機器上。
replicateSet: 副本集 ,如上圖所示 shard1 分片下邊有三個節點(Primary,Secondary,Secondary)。replicateSet 英文名字一看就是複製集合,把一個分片的數據重複拷貝幾份。這樣能夠作到數據容災,當主節點掛掉後,能夠經過選舉機制選出一個節點作主節點,集羣仍能夠正常工做。工做機制以下圖:
mongos :負責路由。全部的對mongodb集羣 請求操做都有它來負責分發。一個集羣中至少有一臺mongos ,固然看本身心情,你能夠多弄幾臺。這樣在項目中用mongo 作爲datasource 你就能夠多配幾個地址。一個路由掛掉了能夠自動選擇其餘路由.
config: 配置服務器。負責記錄集羣中的配置信息,如一個集羣由哪裏分片組成,分片管理權限用戶等等。
其實 分片 和副本集不是必定強求都要作,能夠只用分片功能,或者只用副本集功能。
架構介紹完就是具體一步一步操做了
安裝
大部分系統均可以直接下載壓縮包,直接解壓,添加相應的環境變量便可。
Ubuntu 用apt-get install 安裝
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
sudo echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.0 main" > /etc/apt/sources.list.d/mongodb-org.list
sudo apt-get update
sudo apt-get install -y mongodb-org=3.0.5 mongodb-org-server=3.0.5
mongodb-org-shell=3.0.5 mongodb-org-mongos=3.0.5 mongodb-org-tools=3.0.5
部署
咱們部署採用3臺服務器(每臺機子 2個shard+config server+mongs)。從2.6起,mongodb的配置文件支持yaml格式。
shard1配置
systemLog: destination: file ###日誌存儲位置 path: /XX/shard1.log logAppend: true security: keyFile: /XX/conf/mongo-keyfile # processManagement: fork: true storage: ##journal配置 journal: enabled: true ##數據文件存儲位置 dbPath: /XX/db/shard1/ ##是否一個庫一個文件夾 directoryPerDB: true ##數據引擎 engine: wiredTiger ##WT引擎配置 wiredTiger: engineConfig: ##WT最大使用cache(根據服務器實際狀況調節) cacheSizeGB: 3 ##是否將索引也按數據庫名單獨存儲 directoryForIndexes: true ##表壓縮配置 collectionConfig: blockCompressor: snappy ##索引配置 indexConfig: prefixCompression: true ##端口配置 net: port: 27117 ##副本集 replication: ##oplog大小 oplogSizeMB: 2048 ##複製集名稱 replSetName: rs1 ##分片 sharding: ##分片角色 clusterRole: shardsvr
shard2的配置就改下replSetName 和 端口。
config 配置
systemLog: destination: file ###日誌存儲位置 path: /XX/logs/configsvr.log logAppend: true # processManagement: fork: true security: keyFile: /XX/conf/mongo-keyfile storage: ##journal配置 journal: enabled: true ##數據文件存儲位置 dbPath: /XX/db/config/ ##數據引擎 engine: wiredTiger ##WT引擎配置 wiredTiger: engineConfig: ##WT最大使用cache(根據服務器實際狀況調節) cacheSizeGB: 2 ##是否將索引也按數據庫名單獨存儲 directoryForIndexes: true ##表壓縮配置 collectionConfig: blockCompressor: snappy ##索引配置 indexConfig: prefixCompression: true ##端口配置 net: port: 28017 ##分片 sharding: ##分片角色 clusterRole: configsvr
mongos配置
systemLog: destination: file ###日誌存儲位置 path: /XX/logs/mongos.log logAppend: true security: keyFile: /XX/conf/mongo-keyfile # processManagement: fork: true net: port: 27017 ##分片 sharding: ##config server configDB: host1IP:28017,host2IP:28017,host3IP:28017
三臺機子的配置相同,直接scp 拷貝便可。
啓動
三臺機子先把分片和config 都啓動,而後啓動mongos
mongod --config conf/mongod_shard1.conf mongod --config conf/mongod_shard2.conf mongod --config conf/configsvr.conf
啓動mongos
mongos --config conf/mongos.conf
配置分片副本集合
//shard1 shard2 都須要執行下邊過程。
//鏈接到一個分片上 mongo <server1宿主ip>:27117 //配置副本集 rs.initiate(); rs.add(「<server2宿主ip>:27117」); rs.add(「<server3宿主ip>:27117」); rs.status(); //Fix hostname of primary. cfg = rs.conf(); cfg.members[0].host = "<server1宿主ip>:21117"; rs.reconfig(cfg); rs.status(); //以上命令一個一個執行
路由上添加分片
//鏈接到路由服務器 mongo <宿主ip>:27017 sh.addShard("rs1/<宿主ip>:27017"); sh.addShard("rs2/<宿主ip>:27017"); sh.status();
添加用戶和角色
以上啓動過程都必須在非auth模式下啓動的,配置中不要打開key-file選項(默認打開auth)。若是以auth模式打開,就不能配置用戶和角色了,必須是配置完後,在加key-file選項(auth模式)打開。
直接登陸到mongos 上:
use admin //切換到admin數據庫上 db.createUser({user: "admin",pwd: "pwd",roles: [ { role:"root", db: "admin"} ]}) //這個角色是個超級角色,融合了不少權限。固然也能夠把角色力度分開添加。
從新啓動咱們的mongo集羣,而後在配置中加入key-file選項,以auth模式打開集羣。
導數據
導出: 由舊的2.6 直接導出 mongodump -u usename -p pwd -d dbname --out xxx/ & 導入: mongoDB 3.0兼容2.6導出的數據。 mongorestore -u username -p pwd --authenticationDatabase=dbname restore_data/ -j 1 &(必定要加-j 否者會把機器內存所有幹了了) 以上命令在終端啓動時最好加&,之後臺進程啓動(防止終端鏈接中斷,過程被打斷,數據量大,可能會持續幾個小時…)
監控
1 mongostat -u admin -p pwd --authenticationDatabase=admin 2 tail -10f mongo.log 2 mongotop 不過不能用在mongos 只做用在具體的實例上。
其餘
關閉mongoDB
千萬不要 kill -9 pid,能夠 kill -2 pid 或 db.shutdownServer()
程序驅動
spring-data spring-mongo 升級 ,datasource 配置也須要改變。有些類型映射須要手工轉換(java.util.Date, java.sql.Date)