剛接觸MongoDB,就要用到它的集羣,只能硬着頭皮短期去看文檔和嘗試自行搭建。遷移歷史數據更是讓人惱火,近100G的數據文件,導入、清理垃圾數據執行的速度蝸牛同樣的慢。趁着這個時間,把這幾天關於Mongod集羣相關的內容整理一下。大概介紹一下MongoDB集羣的幾種方式:Master-Slave、Relica Set、Sharding,並作簡單的演示。css
使用集羣的目的就是提升可用性。高可用性H.A.(High Availability)指的是經過儘可能縮短因平常維護操做(計劃)和突發的系統崩潰(非計劃)所致使的停機時間,以提升系統和應用的可用性。它與被認爲是不間斷操做的容錯技術有所不一樣。HA系統是目前企業防止核心計算機系統因故障停機的最有效手段。node
HA的三種工做方式:mongodb
主從方式 (非對稱方式)數據庫
工做原理:主機工做,備機處於監控準備情況;當主機宕機時,備機接管主機的一切工做,待主機恢復正常後,按使用者的設定以自動或手動方式將服務切換到主機上運行,數據的一致性經過共享存儲系統解決。json
雙機雙工方式(互備互援)bash
工做原理:兩臺主機同時運行各自的服務工做且相互監測狀況,當任一臺主機宕機時,另外一臺主機當即接管它的一切工做,保證工做實時,應用服務系統的關鍵數據存放在共享存儲系統中。服務器
集羣工做方式(多服務器互備方式)markdown
工做原理:多臺主機一塊兒工做,各自運行一個或幾個服務,各爲服務定義一個或多個備用主機,當某個主機故障時,運行在其上的服務就能夠被其它主機接管架構
<!--more-->mongoose
主從架構通常用於備份或者作讀寫分離。由兩種角色構成:
主(Master)
可讀可寫,當數據有修改的時候,會將oplog同步到全部鏈接的salve上去。
從(Slave)
只讀不可寫,自動從Master同步數據。
特別的,對於Mongodb來講,並不推薦使用Master-Slave架構,由於Master-Slave其中Master宕機後不能自動恢復,推薦使用Replica Set,後面會有介紹,除非Replica的節點數超過50,才須要使用Master-Slave架構,正常狀況是不可能用那麼多節點的。
還有一點,Master-Slave不支持鏈式結構,Slave只能直接鏈接Master。Redis的Master-Slave支持鏈式結構,Slave能夠鏈接Slave,成爲Slave的Slave。
下面演示一下搭建過程:
1>. 啓動Master
mongod --port 2000 --master --dbpath masterdb/
2>. 啓動Slave
mongod --port 2001 --slave --source 127.0.0.1:2000 --dbpath slavedb/
3>. 給Master裏面導入數據,查看Master和Slave的數據。你會發現導入Master的數據同時也會在Slave中出現。
mongoimport --port 2000 -d test -c dataset dataset.json
mongo --port 2000 test db.dataset.count() > 25359
mongo --port 2001 test db.dataset.count() > 25359
4>. 試一下Master和Slave的寫操做。你會發現,只有Master才能夠對數據進行修改,Slave修改時候會報錯。
mongo --port 2001 test db.dataset.drop() > Error: drop failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" } mongoimport --port 2001 -d test -c dataset dataset.json > Failed: error checking connected node type: no reachable servers
爲了防止單點故障就須要引副本(Replication),當發生硬件故障或者其它緣由形成的宕機時,可使用副本進行恢復,最好可以自動的故障轉移(failover)。有時引入副本是爲了讀寫分離,將讀的請求分流到副本上,減輕主(Primary)的讀壓力。而Mongodb的Replica Set都能知足這些要求。
Replica Set的一堆mongod
的實例集合,它們有着一樣的數據內容。包含三類角色:
主節點(Primary)
接收全部的寫請求,而後把修改同步到全部Secondary。一個Replica Set只能有一個Primary節點,當Primar掛掉後,其餘Secondary或者Arbiter節點會從新選舉出來一個主節點。默認讀請求也是發到Primary節點處理的,須要轉發到Secondary須要客戶端修改一下鏈接配置。
副本節點(Secondary)
與主節點保持一樣的數據集。當主節點掛掉的時候,參與選主。
仲裁者(Arbiter)
不保有數據,不參與選主,只進行選主投票。使用Arbiter能夠減輕數據存儲的硬件需求,Arbiter跑起來幾乎沒什麼大的硬件資源需求,但重要的一點是,在生產環境下它和其餘數據節點不要部署在同一臺機器上。
注意,一個自動failover的Replica Set節點數必須爲奇數,目的是選主投票的時候要有一個大多數才能進行選主決策。
客戶端鏈接單個mongod
和副本集的操做是相同,只須要配置好鏈接選項便可,好比下面是node.js鏈接Replica Set的方式:
mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
奇數個數據節點構成的Replica Set,下面演示精典的3個數據節點的搭建過程。
1> 啓動3個數據節點,--relSet
指定同一個副本集的名字
mongod --port 2001 --dbpath rs0-1 --replSet rs0 mongod --port 2002 --dbpath rs0-2 --replSet rs0 mongod --port 2003 --dbpath rs0-3 --replSet rs0
2> 鏈接到其中一個,配置Replica Set,同時正在執行rs.add
的節點被選爲Primary。開發環境中<hostname>
指的是機器名,生產環境下就是機器的IP。
mongo --port 2001 rs.initiate() rs.add("<hostname>:2002") rs.add("<hostname>:2003") rs.conf()
3> 鏈接Primary節點,導入數據成功。
mongoimport --port 2001 -d test -c dataset dataset.json mongo --port 2001 test db.dataset.count() > 25359
4> 默認狀況下,Secondary不能讀和寫。
mongo --port 2003 test db.dataset.count() > Error: count failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
注意,其中Secondary宕機,不受影響,若Primary宕機,會進行從新選主:
偶數個數據節點,加一個Arbiter構成的Replica Set,下面演示精典的2個數據節點加一個仲裁者的搭建過程。
特別的,生產環境中的Arbiter節點,須要修改一下配置:
journal.enabled = false smallFiles = true
1> 啓動兩個數據節點和一個Arbiter節點
mongod --port 2001 --dbpath rs0-1 --replSet rs0 mongod --port 2002 --dbpath rs0-2 --replSet rs0 mongod --port 2003 --dbpath arb --replSet rs0
2> 鏈接到其中一個,添加Secondary和Arbiter。當僅須要添加Aribiter的時候,只需鏈接當前Replica Set的Primary,而後執行rs.addArb
。
mongo --port 2001 rs.initiate() rs.add("<hostname>:2002") rs.addArb("<hostname>:2003") rs.conf()
當數據量比較大的時候,咱們須要把數據分片運行在不一樣的機器中,以下降CPU、內存和IO的壓力,Sharding就是這樣的技術。數據庫主要由兩種方式作Sharding:縱向,橫向,縱向的方式就是添加更多的CPU,內存,磁盤空間等。橫向就是上面說的方式,如圖所示:
數據分片(Shards)
保存數據,保證數據的高可用性和一致性。能夠是一個單獨的mongod
實例,也能夠是一個副本集。在生產環境下Shard是一個Replica Set,以防止該數據片的單點故障。全部Shard中有一個PrimaryShard,裏面包含未進行劃分的數據集合:
查詢路由(Query Routers)
mongos
的實例,客戶端直接鏈接mongos
,由mongos
把讀寫請求路由到指定的Shard上去。一個Sharding集羣,能夠有一個mongos
,也能夠有多mongos
以減輕客戶端請求的壓力。
配置服務器(Config servers)
保存集羣的元數據(metadata),包含各個Shard的路由規則。
1> 啓動兩個數據分片節點。在此僅演示單個mongod
的方式,Replica Set相似。
mongod --port 2001 --shardsvr --dbpath shard1/ mongod --port 2002 --shardsvr --dbpath shard2/
2> 啓動配置服務器
mongod --port 3001 --dbpath cfg1/ mongod --port 3002 --dbpath cfg2/ mongod --port 3003 --dbpath cfg3/
3> 啓動查詢路由mongos
服務器
mongos --port 5000 --configdb 127.0.0.1:3001,127.0.0.1:3002,127.0.0.1:3003
4> 鏈接mongos,爲集羣添加數據分片節點。
mongo --port 5000 amdmin
sh.addShard("127.0.0.1:2001") sh.addShard("127.0.0.1:2002")
若是Shard是Replica Set,添加Shard的命令:
sh.addShard("rsname/host1:port,host2:port,...") rsname - 副本集的名字
5> 能夠鏈接mongos
進行數據操做了。
mongo --port 5000 test mongoimport.exe --port 5000 -d test dataset.json > 25359 `
MongodDB的備份有多種方式,這裏只簡單介紹一下mongodump
和mongorestore
的用法。
1> 備份和恢復全部db
mongodump -h IP --port PORT -o BACKUPPATH mongorestore -h IP --port PORT BACKUPPATH
2> 備份和恢復指定db
mongodump -h IP --port PORT -d DBNAME -o BACKUPPATH mongorestore -h IP --port PORT -d DBNAME BACKUPPATH mongorestore -h IP --port PORT --drop -d DBNAME BACKUPPATH
3> 備份和恢復指定collection
mongodump -h IP --port PORT -d DBNAME -c COLLECTION -o xxx.bson mongorestore -h IP --port PORT -d DBNAME -c COLLECTION xxx.bson mongorestore -h IP --port PORT --drop -d DBNAME -c COLLECTION xxx.bson
MongoDB的集羣能力仍是很強的,搭建還算是簡單。最關鍵的是要明白上面提到的3種架構的原理,才能用的駕輕就熟。固然不限於MongoDB,或許其餘數據庫也多多少少支持相似的架構。
轉自
高可用的MongoDB集羣 - 簡書http://www.jianshu.com/p/2825a66d6aed